中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

Redis為什么要避免big key

發布時間:2022-03-08 09:42:12 來源:億速云 閱讀:406 作者:小新 欄目:開發技術

這篇文章主要介紹了Redis為什么要避免big key,具有一定借鑒價值,感興趣的朋友可以參考下,希望大家閱讀完這篇文章之后大有收獲,下面讓小編帶著大家一起了解一下。

避免 big key

Redis 執行命令是單線程的,這意味著 Redis 操作「big key」有阻塞的風險。

big key 通常指的是 Redis 存儲的 value 過大。包括:

  • 單個 value 過大。如 200M 大小的 String。

  • 集合元素過多。如 List、Hash、Set、ZSet 中有幾百、上千萬數據。

舉個例子,假設我們有一個 200M 大小的 String key,名稱為「foo」。

執行如下命令

127.0.0.1:6379> GET foo

當返回結果時,Redis 會分配 200m 的內存,并執行 memcpy 拷貝。

void _addReplyProtoToList(client *c, const char *s, size_t len) {
    ...
    if (len) {
        /* Create a new node, make sure it is allocated to at
         * least PROTO_REPLY_CHUNK_BYTES */
        size_t size = len < PROTO_REPLY_CHUNK_BYTES? PROTO_REPLY_CHUNK_BYTES: len;
        // 分配內存(例子中為 200m)
        tail = zmalloc(size + sizeof(clientReplyBlock));
        /* take over the allocation's internal fragmentation */
        tail->size = zmalloc_usable_size(tail) - sizeof(clientReplyBlock);
        tail->used = len;
        // 內存拷貝
        memcpy(tail->buf, s, len);
        listAddNodeTail(c->reply, tail);
        c->reply_bytes += tail->size;

        closeClientOnOutputBufferLimitReached(c, 1);
    }}

而 Redis 輸出 buf 為 16k

// server.h#define PROTO_REPLY_CHUNK_BYTES (16*1024) /* 16k output buffer */typedef struct client {
    ...
    char buf[PROTO_REPLY_CHUNK_BYTES];} client;

這意味著 Redis 無法單次返回響應數據,需要注冊「可寫事件」,從而觸發多次 write 系統調用。

這里有兩個耗時點:

  • 分配大內存(也可能釋放內存,如 DEL 命令)

  • 觸發多次可寫事件(頻繁執行系統調用,如 write、epoll_wait)

那么,如何找出 big key 呢?

如果 slow log 出現了簡單命令,如 GET、SET、DEL,大概率是出現了 big key。

127.0.0.1:6379> SLOWLOG GET
    3) (integer) 201323  // 單位微妙
    4) 1) "GET"
       2) "foo"

其次,可以通過 Redis 分析工具來查找 big key。

$ redis-cli --bigkeys -i 0.1
...
[00.00%] Biggest string found so far '"foo"' with 209715200 bytes

-------- summary -------

Sampled 1 keys in the keyspace!
Total key length in bytes is 3 (avg len 3.00)

Biggest string found '"foo"' has 209715200 bytes

1 strings with 209715200 bytes (100.00% of keys, avg size 209715200.00)
0 lists with 0 items (00.00% of keys, avg size 0.00)
0 hashs with 0 fields (00.00% of keys, avg size 0.00)
0 streams with 0 entries (00.00% of keys, avg size 0.00)
0 sets with 0 members (00.00% of keys, avg size 0.00)
0 zsets with 0 members (00.00% of keys, avg size 0.00)

對于 big key,有以下幾點建議:

1.業務中盡量避免 big key 出現。當出現 big key 時,你要判斷這樣設計是否合理,又或者是出現了 bug。

2.將 big key 拆分為多個小 key。

3.使用替代命令。

  • 如果 Redis 版本大于 4.0,可使用 UNLINK 命令替代 DEL。Redis 版本大于 6.0,可開啟 lazy-free 機制。將釋放內存操作,放到后臺線程執行。

  • LRANGE、HGETALL 等替換為 LSCAN、HSCAN 分次獲取。

但我還是建議在業務中避免 big key。

感謝你能夠認真閱讀完這篇文章,希望小編分享的“Redis為什么要避免big key”這篇文章對大家有幫助,同時也希望大家多多支持億速云,關注億速云行業資訊頻道,更多相關知識等著你來學習!

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

池州市| 拉孜县| 绩溪县| 涟水县| 宜黄县| 东源县| 顺昌县| 原阳县| 铜鼓县| 常州市| 木里| 工布江达县| 蓝山县| 无极县| 永年县| 双流县| 连山| 恩平市| 乌鲁木齐县| 丰都县| 资讯| 黄梅县| 汉中市| 扎鲁特旗| 鹤山市| 伽师县| 昌平区| 灵寿县| 辽宁省| 田阳县| 绥宁县| 仙游县| 肇东市| 汽车| 八宿县| 蓬安县| 沅陵县| 连城县| 芷江| 井冈山市| 阜宁县|