--- tags: Redis --- # 10.Scaling Redis * 擴展讓redis能處理更大資料根更複雜的運算 --- ## 1. Scaling reads 1. 使用第9章的短結構 2. 根據程式需要查詢的類型, 選擇能提供這種查詢最適當的類型. 比方:不要把LISTs 當 SETs 3. 較大的資料在寫進redis前先比較 lz4、gzip、bzip2, 看哪一個壓縮效果跟性能最好 4. 新增 read-only slave servers * 新增方式:將 redis config檔增加 slaveof host port, 再將 host、port改為主 redis的資訊 * 疑慮:若連接太多 slave, 主服務器會需要發送太多快照, 使得主服務延遲 * 解決方式: 1. 以下圖的結構減少 redis master要傳送快照給slave的數量 ![](https://i.imgur.com/oV76wrZ.png) 2. 先進行壓縮, 減少要傳送的資料量. 用SSH to tunnel的連線可降低頻寬、使用openVPN進行壓縮 * Redis sentinel:可以配合redis的複製功能使用, 當master故障時能立刻進行轉移 * sentinel監視服務:向 master 發送 PUBLISH/SUBSCRIBE, 並向 master、slave發送PING來識別所有可用的slave. 當 master當機時, sentinel就可以通過有的資訊來選出新的master --- ## 2. Scaling writes and memory capacity 用分片(sharding in the context, 第9章的手法)的機制不僅可以增加記憶體的總數量, 同時也能在寫性能達到上限時,提升redis的寫性能. 本單元主要通過分片來擴展 redis 1. 確認是否已用盡所有方式來降低記憶體, 並盡可能減少需要寫入的資料量 * 檢查程式是用最少的redis讀取量 * 將無關的功能移到其他服務器上(參考ch5) * 在對redis寫入前先整理好要寫入的資料(參考ch6) * 用 lock 取代 WATCH/MULTI/EXEC(會有速度限制), 也可以使用ch11的Lua * 如果使用 AOF, 硬碟會將所有動作數據都儲存起來, 這需要花費一定時間, 因此指另可以多但一定要簡短 2. 處理分片(shard)的配置訊息(configuration) 1. 使用python裝飾器獲得配置訊息(參考ch5), 接著把該配置訊息與已經有的進行比對, 根據比對結果來決定是否創新的連接, 根據ch5 信息儲存的格式為 config:redis:<component> ![](https://i.imgur.com/53cnM2d.png) 2. 根據分片的信息來獲得連線, 若裝飾器不能使用則可以參考此方法 ![](https://i.imgur.com/rCtjY5p.png) 3. 通過2的get_sharded_connection, 模仿裝飾器寫出能自動創建分片的程式,並且還能直接傳遞連線給底層函數 ![](https://i.imgur.com/2sGHHlt.png) 舉例:將 Sets 分到16台機器上, 這些機器的配置會被編成Json字串並儲存從config:redis:unique:0 到 config:redis:unique:15, 至於每天的呼叫次數會被儲存到沒有被分片的redis的y config:redis:unique ![](https://i.imgur.com/KSWtkXe.png) --- ## 3. Scaling complex queries 查詢比讀寫更複雜,因此只對數據做分片是不夠的 1. 通過添加 query slave 來擴展搜尋量 * 根據ch7搜尋需要使用到 SUNIONSTORE, SINTERSTORE, SDIFFSTORE, ZINTERSTORE, and/or ZUNIONSTORE, 這些都需要對 redis 進行寫入, 因此需要先將 slave 的 slave-read-only 從預設的 yes 改為 no, 如此搜尋就能在 slave 上進行, 要注意到搜尋的結果只會暫存在執行搜尋的機器上, 因此若有需要重複查詢需要執行些定期持久化操作 2. Scaling search index size 數據量超過記憶體時採取的方法 * 為了將搜尋要求進行分片, 先將搜尋index進行分片, 確保每個索引文檔內的所有數據都會儲存在同一分片 (方法參考 ch7 index_document()), 如此只要對分片進行查詢就能獲得搜尋結果. 搜尋方法由索引的類型分為 **SORT-based 和 ZSET-based**. * **SHARDING SORT-BASED SEARCH**(基於SORT的搜尋操作進行分片) 1. 編寫一個能在單個分片上執行查詢的程式 ![](https://i.imgur.com/KTatqZD.png) ![](https://i.imgur.com/uSBDKPK.png) search_get_values能從單個分片裡獲得所有必需的訊息 2. 在所有分片上執行1.的查詢程式 下圖的get_shard_results會一個接一個對所有分片進行搜尋, 要注意為了對所有分片進行搜尋num需要是正確的分片總數 ![](https://i.imgur.com/XFZeLFA.png) 3. 對各分片的查詢結果進行合併, 選出想要的部分結果 下圖重新對所有結果進行排序, 注意數字及非數字排序之間的區別, 並謹慎處理缺失及排數字時遇到非數字的值 ![](https://i.imgur.com/Hrhib8J.png) * **SHARDING ZSET-BASED SEARCH** 1. 根據 Sets 來對所有分片進行搜尋 包裝 search_and_zsort() (ch7) 在 ZSETs, 比10.5還更簡單, 他忽略沒有分值的結果, 直接從暫存後的 Sets 中獲得帶有值的結果 ![](https://i.imgur.com/h1D8Qd7.png) 2. 對每個分片進行搜尋後, 接著合併所有分片結果 ![](https://i.imgur.com/nVEBPmd.png) ![](https://i.imgur.com/6LofhGV.png)