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

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 运维知识 > 数据库 >内容正文

数据库

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

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

文章目錄

  • 鍵值設計
    • key設計
    • value設計
      • big key
        • 定義
        • 反例
        • bigkey的產生
        • 如何優化bigkey
        • 刪除bigKey的注意事項
        • bigkey的危害


鍵值設計

key設計

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

    以業務名(或數據庫名)為前綴(防止key沖突),用冒號分隔,比如業務名:表名:id
    o2o:order:1


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

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


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

    反例:包含空格、換行、單雙引號以及其他轉義字符


value設計

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

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

    反例:

    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設置過期時間(條件允許可以打散過期時間,防止集中過期)

big key

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


定義

其實不然,按照經驗來說 ,如何定義bigKey 呢?

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

一般來說,string類型控制在10KB以內,hash、list、set、zset元素個數不要超過5000。當然了這不是絕對的,請依據場景,靈活處理。


反例

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


bigkey的產生

一般來說,bigkey的產生都是由于程序設計不當,或者對于數據規模預料不清楚造成的,來看幾個例子:

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

如何優化bigkey

核心思想: 分治 拆分


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

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

  • 【推薦】:選擇適合的數據類型

    例如:實體類型(要合理控制和使用數據結構,但也要注意節省內存和性能之間的平衡)
    反例:

    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設置過期時間(條件允許可以打散過期時間,防止集中過期)。


刪除bigKey的注意事項

對于非字符串的bigkey,比如 hash list set zset , 不要使用del 刪除, 請使用 hscan 、sscan、zscan方式漸進式刪除。

同時要注意防止bigkey過期時間自動刪除問題(例如一個100萬的hash設置1小時過期,會觸發del操作,造成阻塞)


bigkey的危害

  • 導致redis阻塞

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

  • 導致網絡擁塞

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


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

    針對那種我們設置了過期時間的big key , 在redis4.0前,沒有lazy free功能,我們只能通過類似scan big key,每次刪除少量的元素,分多次刪除;但在面對“被動”刪除鍵的場景,這種取巧的刪除就無能為力。

    舉個例子:Redis Cluster大集群,業務緩慢地寫入一個帶有TTL的2000多萬個字段的Hash鍵,當這個鍵過期時,redis開始被動清理它時,導致redis被阻塞20多秒,結果發生了fail over ,造成故障。

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

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

    redis4.0有lazy free功能后,這類主動或被動的刪除big key時,時間復雜度O(1)。

總結

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

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。