--- tags: Redis --- # CH9. Reducing memory use 降低內存佔用優點 * 減少創建快照和加載快照所需的時間 * 提升寫入 AOF 文件和重寫 AOF 文件時的效率 * 縮短從服務器進行同步所需的時間 ## 9.1 Short Structures * LISTs. SETs. HASHs. ZSETs * 在LISTs. HASHs. ZSETs 長度較短時,可以使用ziplist來儲存 * ziplist: unstructured * LIST: doubly linked list * HASH: hash table * ZSET: hash table + skiplist * 上面三種每次被讀取的時候都要進行解碼,每次被寫入的時候也要進行局部的重新編碼,並且可能需要對內存的數據進行移動 * doubly linked list: * 三個指針 * 指向前一個node的指針 * 指向後一個node的指針 * 指向node包含的字符串值的指針 * 字符串值 * 字符串的長度 * 字符串剩餘可用的字節數 * 以空字符結尾的字符串本身 * 3 * 4 + 2 * 4 + 1 = 21 ![](https://i.imgur.com/UeI6c8A.png) * ziplist: * 压缩列表是由结点(非真实结点)组成的序列 (sequence) ,每个结点都由两个长度值和一个字符串组成。 * node組成的序列,每個node都由兩個長度值和一個字符串組成 * 2 * 压缩列表是通过避免存储额外的指针和元数据,从而达到降低额外的开销。 * 耨過避免儲存額外的指針和元數據,從而達到降低額外的開心 * The intset encoding for SETs * 如果集合的所有成員都可以被解析為十進位整數,並且成員的數量足夠少,Redis 就會以有序整數數組的方式存儲集合,稱為intset * 降低內存消耗、提升所有 SET 操作的執行速度 * Performance issues for long ziplists and intsets 將 ziplist 的長度限制在 1024 個元素內,並且每個元素不能超過 64 個字節,對於大多數這種配置可兼顧低內存佔用和高性能兩個優點 ## 9.2 Sharded structures * sharding 本質上就是基於某些簡單的規則將數據劃分為更小的部分,然後根據數據所屬的部分來決定將數據發送到哪個位置 * 這種技術可以擴展儲存空間並提高所能處理的負載量 * value X 儲存到 key Y 里面,而是將 value X 儲存到 key Y:shardid 裡面。 * Lists 在不使用 Lua 腳本的狀況下進行分配非常困難 * ZSETs 相關指令需要對 ZSET 的所有分片進行操作才能計算出指令的最終結果,所以這些操作無法運行的像普通的 SET 操作那麼快,因此對 ZSET 進行分片的作用不大 * HASHes 把 HASH 的 key 作為一個信息源,透過 hash function 計算出一個值 根據需要儲存的 key 的總數量與每個 key 需要儲存的 key 數量,計算出所需的分片數 使用分片數和 hash 決定應該 key 儲存到哪個分片裡面 ![](https://i.imgur.com/SleCC9L.png) * SETs 如果集合的所有成員都可以被解析為十進位整數,採用 intset 再存入sharded sets ## 9.3 Packing bits and bytes * 通過四個命令,可以在不對數據進行壓縮的情況下,使用 Redis 字符串以盡可能緊湊的格式去儲存 * GETRANGE: 用於讀取被儲存字符串的其中一部分內容 * SETRANGE: 用於對儲存在字符串裡面的其中一部分內容進行設置 * GETBIT: 用於獲取字符串裡面某個二進制位的值 * SETBIT: 用於對字符串裡面某個二進制位進行設置 * 假如某個用戶需要儲存中國、廣東省這兩個信息,採用 utf-8,那麼至少需要消耗 5*3=15 個字節。用新的方式只需要 2 個字節