Redis 實戰 —— 13. 擴展 Redis

簡介

當數據量增大或者讀寫請求增多後,一臺 Redis 服務器可能沒辦法再存儲全部數據或者處理全部讀寫請求,那麼就須要對 Redis 進行擴展,保證 Redis 在能存儲全部數據對狀況下,同時能正常處理讀寫請求。 P227git

擴展讀性能 P227

提升性能的幾個途徑 P228
  • 使用短結構:確保壓縮列表的最大長度不會太大
  • 根據查詢類型選擇結構
    • 不要把列表看成集合使用
    • 不要獲取整個散列,而後再客戶端裏面進行排序,而應使用有序集合
  • 大致積對象存儲前進行壓縮:減小讀寫所需的網絡帶寬。對比 lz4, gzip 和 bzip2 等壓縮算法,選擇對存儲數據壓縮效果和性能最好對壓縮算法
  • 流水線和鏈接池:複製、處理故障、事務及性能優化 中介紹過流水線

擴展讀性能最簡單的方法就是添加只讀服務器(複製、處理故障、事務及性能優化 中介紹過經過複製 (replication) 讓一個 Redis 服務器成爲從服務器及運做原理和管理方法),並只對主服務器進行寫入(默認狀況下,嘗試對一個從服務器進行寫入將引起一個錯誤,即便它是其餘從服務器的主服務器)。 P228github

添加從服務器 P228
  • 在配置文件中加上: slaveof <master-host> <master-port>
  • 向正在運行對 Redis 服務器發送: SLAVEOF <master-host> <master-port>

能夠通向從服務器發送 SLAVEOF NO ONE 命令讓其與主服務器斷開。 P228redis

當一個主服務器有大量從服務器時,那麼它們之前同步時就會耗盡大部分帶寬,致使主服務器延遲變高,甚至致使主服務器斷開和從服務器的鏈接。 P229算法

解決從服務器重同步 (resync) 問題的方法 P229數據庫

  • 構建樹狀的從服務器羣組:經過構建二級從服務器下降主服務器須要傳遞給從服務器的數據量
  • 對網絡鏈接進行壓縮:使用帶壓縮帶 SSH 隧道 (tunnel) 進行鏈接能夠明顯地下降帶寬(注意使用 SSH 提供的選項讓 SSH 鏈接在斷線後自動鏈接)
故障轉移 P230

Redis Sentinel 能夠配合 Redis 的複製功能使用,並對下線的主服務器進行故障轉移。 Redis Sentinel 是運行在特殊模式下的 Redis 服務器,它會監視一系列主服務器以及它們的從服務器,經過向主服務器發送 PUBLISH 命令和 SUBSCRIBE 命令,並向主服務器和從服務器發送 PING 命令,各個 Sentinel 進程能夠自主識別可用的從服務器和其餘 Sentinel 。當主服務器失效時,監視這個主服務器的全部 Sentinel 就會基於彼此共有的信息選出一個 Sentinel ,並從現有的從服務器中選擇一個新的主服務器。而後被選中的 Sentinel 就會讓剩餘的其餘從服務器去複製這個新的主服務器(默認設置下, Sentinel 會一個接一個地遷移從服務器,但這個數量能夠經過配置選項進行修改)。 P230性能優化

Redis Sentinel 還提供了可選的故障轉移通知功能,這個功能能夠經過調用用戶提供的腳原本執行配置更新等操做。 P230服務器

擴展寫性能和內存容量 P230

下降內存佔用,減小需寫入的數據 P231
  • 減小程序須要讀取的數據量
  • 無關功能遷移至其餘服務器
  • 寫入 Redis 前,嘗試內存中進行聚合(能夠應用於分析和統計計算)
  • 使用鎖或者 Lua 腳本代替 WATCH/MULTI/EXEC 事務
  • 使用 AOF 持久化會將寫入的全部數據存儲起來,能夠考慮配置重寫 AOF 或使用 RDB

當使用上述方法沒法繼續下降內存並提高性能以後,就說明已經遇到了只使用一臺機器帶來的瓶頸,那麼就須要將數據分片到多臺機器上面。咱們介紹使用固定分片數量的方法,使得分片方案可以知足將來幾年的預期,假設分片爲 256 片。那麼前期在數據量很是小的狀況下不必每一個 Redis 服務器都使用獨立的機器,能夠多個 Redis 服務器共用一臺機器,或者每一個 Redis 服務器使用多個 Redis 數據庫。 (注意:每臺機器上運行多個 Redis 服務器時,確保監聽不一樣的端口,並確保服務器寫入的都是不一樣的快照文件/ AOF 文件。)P231網絡

分片方法能夠直接採用 下降內存佔用 中提到的先使用散列函數計算出一個數字散列值,而後使用分片數量計算出當前採用哪一個鏈接便可,即再也不對 key 進行分片,而是轉換爲對鏈接進行分片。 P234多線程

若是執行復雜查詢時,感受性能受到了 Redis 單線程設計的限制,而且機器有更多的計算核心、更多的通訊網絡資源,以及更多用於存儲快照文件和 AOF 文件的磁盤 I/O ,那麼能夠考慮在單臺機器上面運行多個 Redis 服務器。(固然也須要注意:確保一臺機器上的多個 Redis 服務器監聽不一樣的端口,並確保服務器寫入的都是不一樣的快照文件/ AOF 文件。) P234併發

所思

若是網絡 I/O 成爲瓶頸的話,那麼也能夠考慮 Redis 6.0 的多線程特性。多線程特性主要是改進讀寫緩衝區的性能,由於這部分時間佔比較大,而命令執行部分仍然使用單線程處理。這樣既能提升總體性能,又能夠保持設計簡單,也不會引入新的併發問題。

對於一些全局惟一的數據,例如:惟一訪問計數器等,能夠額外使用一個鏈接專門存儲相似的數據。

擴展複雜查詢 P234
擴展搜索查詢量 P235

實現內容搜索、定向廣告和職位搜索 中提到的各類搜索方法都使用了相似 SUNIONSTORE, SINTERSTORE, SDIFFSTORE, ZINTERSTORE, ZUNIONSTORE 等命令,而這些命令都須要對 Redis 進行寫入,因此前面介紹的只讀從服務器將沒法處理這些搜索。 P235

爲了執行上述搜索,須要開啓對從服務器對寫入功能。 Redis 對配置文件中, slave-read-only 選項控制可否對從服務器進行寫入,默認值爲 yes 。因此只要將 slave-read-only 設置爲 no 並重啓從服務器,上述搜索便可正常執行。 P235

當機器擁有足夠多的內存,而且它執行的都是隻讀操做(或者說這些操做不會修改其餘查詢所使用的底層數據)的時候,添加從服務器可以幫助咱們實現橫向擴展 (scale out) 。

擴展搜索索引大小 P235

爲了對搜索查詢進行鏈接分片,咱們必須先對搜索索引進行鏈接分片,確保對於每一個被索引的文檔來講,同一個文檔的全部數據都會被存儲到同一個鏈接分片裏面。 P236

分片搜索實際流程大體分爲如下三個操做:

  • 編寫可以在單個分片上面執行對查詢程序,讓它進行搜索並獲取待排序對搜索結果
  • 在全部分片執行上面提到的查詢程序
  • 對各個分片對查詢結果進行合併,而後選出想要的那部分結果

注意:因爲沒法肯定分頁結果中的每條數據分別來自哪一個分片,因此爲了確保返回的數據在 [start, start + num] 內,程序須要從每一個分片獲取 [0, start + num] 內的數據,而後在內存中選出最終結果。 P236

所思

分片其實也就兩種形式:

  • 對鍵進行分片:適用於大量相似鍵,但每一個鍵對應的數據量不大的狀況
  • 對數據進行分片:適用於每一個鍵對應對數據量很大的狀況

對鍵進行分片基本和鏈接分片綁定了,由於大量鍵只有在多鏈接對狀況下分片纔有用;而對數據進行分片既能夠在單個鏈接中變成多個鍵,也能夠轉化成鏈接分片。

本文首發於公衆號:滿賦諸機(點擊查看原文) 開源在 GitHub :reading-notes/redis-in-action

相關文章
相關標籤/搜索