---
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的數量

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>

2. 根據分片的信息來獲得連線, 若裝飾器不能使用則可以參考此方法

3. 通過2的get_sharded_connection, 模仿裝飾器寫出能自動創建分片的程式,並且還能直接傳遞連線給底層函數

舉例:將 Sets 分到16台機器上, 這些機器的配置會被編成Json字串並儲存從config:redis:unique:0 到 config:redis:unique:15, 至於每天的呼叫次數會被儲存到沒有被分片的redis的y config:redis:unique

---
## 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. 編寫一個能在單個分片上執行查詢的程式


search_get_values能從單個分片裡獲得所有必需的訊息
2. 在所有分片上執行1.的查詢程式
下圖的get_shard_results會一個接一個對所有分片進行搜尋, 要注意為了對所有分片進行搜尋num需要是正確的分片總數

3. 對各分片的查詢結果進行合併, 選出想要的部分結果
下圖重新對所有結果進行排序, 注意數字及非數字排序之間的區別, 並謹慎處理缺失及排數字時遇到非數字的值

* **SHARDING ZSET-BASED SEARCH**
1. 根據 Sets 來對所有分片進行搜尋
包裝 search_and_zsort() (ch7) 在 ZSETs, 比10.5還更簡單, 他忽略沒有分值的結果, 直接從暫存後的 Sets 中獲得帶有值的結果

2. 對每個分片進行搜尋後, 接著合併所有分片結果

