日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 运维知识 > 数据库 >内容正文

数据库

Redis进阶-Redis键值设计及BigKey问题

發(fā)布時(shí)間:2025/3/21 数据库 56 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Redis进阶-Redis键值设计及BigKey问题 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

文章目錄

  • 鍵值設(shè)計(jì)
    • key設(shè)計(jì)
    • value設(shè)計(jì)
      • big key
        • 定義
        • 反例
        • bigkey的產(chǎn)生
        • 如何優(yōu)化bigkey
        • 刪除bigKey的注意事項(xiàng)
        • bigkey的危害


鍵值設(shè)計(jì)

key設(shè)計(jì)

  • (1)【建議】: 可讀性和可管理性

    以業(yè)務(wù)名(或數(shù)據(jù)庫名)為前綴(防止key沖突),用冒號(hào)分隔,比如業(yè)務(wù)名:表名:id
    o2o:order:1


  • (2)【建議】:簡潔性

    保證語義的前提下,控制key的長度,當(dāng)key較多時(shí),內(nèi)存占用也不容忽視,例如:
    user:{uid}:friends:messages:{mid} 簡化為 u:{uid}🇫🇷m:{mid}


  • (3)【強(qiáng)制】:不要包含特殊字符

    反例:包含空格、換行、單雙引號(hào)以及其他轉(zhuǎn)義字符


value設(shè)計(jì)

  • (1)【強(qiáng)制】:拒絕bigkey(防止網(wǎng)卡流量、慢查詢)

  • (1)(2)【推薦】:選擇適合的數(shù)據(jù)類型。
    例如:實(shí)體類型(要合理控制和使用數(shù)據(jù)結(jié)構(gòu),但也要注意節(jié)省內(nèi)存和性能之間的平衡)

    反例:

    set user:1:name tomset user:1:age 19set user:1:favor football

    正例:

    hmset user:1 name tom age 19 favor football

  • (1)3.【推薦】:控制key的生命周期,redis不是垃圾桶
    建議使用expire設(shè)置過期時(shí)間(條件允許可以打散過期時(shí)間,防止集中過期)

big key

我們知道,Redis 的一個(gè)字符串最大512M,一個(gè)二級(jí)數(shù)據(jù)結(jié)構(gòu)(比如 hash、list、set 、zset)可以存儲(chǔ)2^32-1 個(gè)元素 ,約40億個(gè)元素。 但是不是以為著我們可以任意存儲(chǔ)元素呢? 時(shí)刻牢記,在讀寫這個(gè)角度上,目前Redis還是單線程的。


定義

其實(shí)不然,按照經(jīng)驗(yàn)來說 ,如何定義bigKey 呢?

  • 字符串類型:它的big體現(xiàn)在單個(gè)value值很大,一般認(rèn)為超過10KB就是bigkey。
  • 非字符串類型:哈希、列表、集合、有序集合,它們的big體現(xiàn)在元素個(gè)數(shù)太多。

一般來說,string類型控制在10KB以內(nèi),hash、list、set、zset元素個(gè)數(shù)不要超過5000。當(dāng)然了這不是絕對(duì)的,請(qǐng)依據(jù)場(chǎng)景,靈活處理。


反例

我們來看個(gè)反例: 一個(gè)hash 存儲(chǔ)用戶信息,我有100萬用戶,我全都放到一個(gè)key里。。。。這不管從哪個(gè)角度看 ,bigkey無疑。


bigkey的產(chǎn)生

一般來說,bigkey的產(chǎn)生都是由于程序設(shè)計(jì)不當(dāng),或者對(duì)于數(shù)據(jù)規(guī)模預(yù)料不清楚造成的,來看幾個(gè)例子:

  • 社交類:粉絲列表,如果某些明星的粉絲數(shù)據(jù),如果不精心設(shè)計(jì)下,一個(gè)明星的粉絲 百萬很少了吧,你都把這百萬的粉絲數(shù)據(jù)放到一個(gè)key中存儲(chǔ),毫無疑問是bigkey
  • 統(tǒng)計(jì)類:比如按天存儲(chǔ)某項(xiàng)功能或者網(wǎng)站的用戶集合,用戶很少,倒是沒多大問題,一旦用戶多了起來,必是bigkey
  • 緩存類:將數(shù)據(jù)從數(shù)據(jù)庫加載出來以后序列化放到Redis里,這個(gè)方式非常常用,但有兩個(gè)地方需要注意,第一,是不是有必要把所有字段都緩存;第二,有沒有相關(guān)關(guān)聯(lián)的數(shù)據(jù),不要為了圖方便把相關(guān)數(shù)據(jù)都存一個(gè)key下,產(chǎn)生bigkey。

如何優(yōu)化bigkey

核心思想: 分治 拆分


  • big list: list1、list2、…listN
    big hash:可以講數(shù)據(jù)分段存儲(chǔ),比如一個(gè)大的key,假設(shè)存了1百萬的用戶數(shù)據(jù),可以拆分成 200個(gè)key,每個(gè)key下面存放5000個(gè)用戶數(shù)據(jù)

  • 如果bigkey不可避免,也要思考一下要不要每次把所有元素都取出來(例如有時(shí)候僅僅需要
    hmget,而不是hgetall),刪除也是一樣,盡量使用優(yōu)雅的方式來處理

  • 【推薦】:選擇適合的數(shù)據(jù)類型

    例如:實(shí)體類型(要合理控制和使用數(shù)據(jù)結(jié)構(gòu),但也要注意節(jié)省內(nèi)存和性能之間的平衡)
    反例:

    set user:1:name tom set user:1:age 19 set user:1:favor football

    正例:

    hmset user:1 name tom age 19 favor football
  • 【推薦】:控制key的生命周期,redis不是垃圾桶

    建議使用expire設(shè)置過期時(shí)間(條件允許可以打散過期時(shí)間,防止集中過期)。


刪除bigKey的注意事項(xiàng)

對(duì)于非字符串的bigkey,比如 hash list set zset , 不要使用del 刪除, 請(qǐng)使用 hscan 、sscan、zscan方式漸進(jìn)式刪除。

同時(shí)要注意防止bigkey過期時(shí)間自動(dòng)刪除問題(例如一個(gè)100萬的hash設(shè)置1小時(shí)過期,會(huì)觸發(fā)del操作,造成阻塞)


bigkey的危害

  • 導(dǎo)致redis阻塞

    這個(gè)也很好理解: 我們知道Redis 官方號(hào)稱10萬QPS, 我們通常打不到這個(gè)值,但是大幾萬的QPS還是沒問題的,這也就意味著 redis 的執(zhí)行速度 1秒幾萬條, 速度相當(dāng)?shù)目斓摹?假設(shè)你有個(gè)bigKey , 操作一次耗時(shí)1秒,那Redis 單線程 在這1秒鐘就只能處理你這個(gè)Key, 后面堵了一堆請(qǐng)求。。。。 并且你的應(yīng)用 序列化和反序列化這種大key , 也消耗CPU 。

  • 導(dǎo)致網(wǎng)絡(luò)擁塞

    假設(shè)我們的交換機(jī),千兆網(wǎng)絡(luò)(小b),那么 實(shí)際帶寬 1024 / 8 = 128M . 假設(shè)你的這個(gè)key的大小 500KB, 客戶端并發(fā) 1000獲取這個(gè)key, 那么就意味著 1000 * 500KB = 500M ,那就是每秒產(chǎn)生500M的流量。先不說你的Redis能不能處理的過來這個(gè)并發(fā)下的bigKey,單說你的這個(gè)千兆網(wǎng)絡(luò), 你說你這個(gè)網(wǎng)絡(luò)I/O能扛得住嗎? 一般服務(wù)器會(huì)采用單機(jī)多實(shí)例的方式來部署,也就是說一個(gè)bigkey可能會(huì)對(duì)其他實(shí)例也造成影響,其后果不堪設(shè)想。


  • 過期刪除- Redis4.0新特性(三)-Lazy Free

    針對(duì)那種我們?cè)O(shè)置了過期時(shí)間的big key , 在redis4.0前,沒有l(wèi)azy free功能,我們只能通過類似scan big key,每次刪除少量的元素,分多次刪除;但在面對(duì)“被動(dòng)”刪除鍵的場(chǎng)景,這種取巧的刪除就無能為力。

    舉個(gè)例子:Redis Cluster大集群,業(yè)務(wù)緩慢地寫入一個(gè)帶有TTL的2000多萬個(gè)字段的Hash鍵,當(dāng)這個(gè)鍵過期時(shí),redis開始被動(dòng)清理它時(shí),導(dǎo)致redis被阻塞20多秒,結(jié)果發(fā)生了fail over ,造成故障。

    Redis 4.0提供了過期異步刪除(lazyfree-lazyexpire yes)

    lazy free 惰性刪除或延遲釋放: 當(dāng)刪除鍵的時(shí)候,redis提供異步延時(shí)釋放key內(nèi)存的功能,把key釋放操作放在Background I/O單獨(dú)的子線程處理中,減少刪除big key對(duì)redis主線程的阻塞,有效地避免刪除big key帶來的性能和可用性問題。

    redis4.0有l(wèi)azy free功能后,這類主動(dòng)或被動(dòng)的刪除big key時(shí),時(shí)間復(fù)雜度O(1)。

總結(jié)

以上是生活随笔為你收集整理的Redis进阶-Redis键值设计及BigKey问题的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。