redis介紹
redis作為一個開源的kv數據庫在互聯網公司被廣泛應用。
作為nosql的一員redis有這幾個優點:
- KV存儲
- 支持多種數據結構
- 全內存存儲
- 持久化
- 主從復制
- 集群模式
- 社區活躍,文檔齊全
事物都不是完美的,redis也有不少缺點:
- 2.x時代原生的故障自動轉移恢復功能比較弱(senteinel出現的還比較晚)
- 在線擴容,縮容麻煩
- 主從復制采用全量復制的方式(2.8x之前使用fsync,2.8x之后使用psync)
- 如果單實例數據量過大,遭遇雪崩,重啟恢復數據很痛苦
redis代理介紹
為了解決上述的缺點,互聯網公司主要提出了三種類型的技術
1.客戶端分片
特點:
由客戶端自己計算key在哪個機器上存儲和查找,和后端服務器沒有什么關系,降低了redis server集群的復雜度,增加了開發的難度。
缺點:
但是客戶端要實時知道,集群節點的信息狀態,新增節點的時候客戶端要支持動態的sharding,但是多數客戶端不支持,因此沒有大規模使用。
客戶端分片圖例
2.代理分片
此方式是借助一個代理服務器實現數據分片,客戶端直接與proxy聯系,proxy計算集群節點信息,並把請求發送到對應的集群節點。
代表應用:
- twemproxy
- codis
twemproxy
twitter 開發。它主要通過事件驅動模型來達到高並發,每收到一個請求,通過解析請求,發送請求到后端服務,再等待回應,發送回請求方。有這幾個特點:
- 事件驅動模型
- 三種分片算法
- C語言開發
- 支持大部分redis命令
- 配置簡單
- 支持狀態監控
架構圖(來源於網絡)
由於twemprox本身是單點的因此 經常和高可用軟件搭配使用
配置示例:
xxxx:
listen: 127.0.0.1:4097
hash: fnv1a_64
distribution: ketama
auto_eject_hosts: true
redis: true
server_retry_timeout: 2000
server_failure_limit: 1
servers:
- 127.0.0.1:6378:1
distribution:為一致性哈希算法
servers:為后端緩存服務,twemproxy可以預先連接每個server或者不,根據接收到的請求具體分析出key,然后根據key來選擇適當的server。
twemproxy使用要點:
- 合理設置twemproxy請求redis的timeout參數
- 對緩存和存儲服務,分別設置redis eject策略
- 根據數據大小設置mbuf的大小
- pipeline請求不宜過大,過大導致twemproxy申請大量的內存空間
- 跨機房注意client-output-buffer-limit normal &&client-output-buffer-limit slave
codis
codis 由豌豆莢的團隊編寫,也是采用代理分片的技術。
- Go語言編寫
- 相比twemproxy 限制少,支持動態擴容縮容。
- 有管理界面,對后期維護友好
- 依賴ZK
- Codis-proxy不支持熱重啟
架構圖(來源於網絡)
Codis組件:
- Codis Server: 就是后端的redis
- Codis Proxy: 客戶端鏈接reids的代理組件,實現redis協議
- Dashboard 集群的管理工具
- Admin: 集群管理的命令行工具。
- FE: 集群管理界面。
- ZooKeeper : 存放數據路由表和codis-proxy節點的元信息
Codis怎么分片?
Codis 采用 Pre-sharding 的技術來實現數據的分片, 默認分成 1024 個 哈希槽。其實就是預分片,將這些分布式狀態保存在ZK中,最大后端支持1024個redis server。另外每個哈希槽必須有個對應的組id,數據遷移和redis cluster 一樣由哈希槽為單位。
3.服務端分片
客戶端隨意與集群中的任何節點通信,服務器端負責計算某個key在哪個機器上,當客戶端訪問某台機器時,服務器計算對應的key應該存儲在哪個機器,然后把結果返回給客戶端,客戶端再去對應的節點操作key,是一個重定向的過程,目前官方的Redis Cluster 集群支持
特點:
- 無中心架構
- 數據按照s哈希槽存儲分布在多個redis實例上
- 實現故障自動轉移
- 集群內部增加slave做數據副本,用於集群快速恢復
- 可手動踢出節點,為升級和遷移提供可操作方案
Redis Cluster 如何分片?
采用CRC16(key) % 16384 來計算鍵 key 屬於哪個槽,其中 CRC16(key) 語句用於計算鍵 key 的 CRC16 校驗和。
如何進行故障轉移?
當主節點down掉之后,選舉出一個從成為新的主
被選中的從執行slave no one 成為新的主
新主撤銷down掉主的哈希槽指派,把這些哈希槽指派給自己
新主和集群其他節點進行通信,廣播自己是主了
新主開始接收請求和哈希槽指派
如何選舉?
從在集群中屬於冷備,讀寫請求都不會發往從節點。
從發現自己的主down掉之后,會廣播一條 cluster_type_fallover_auth_reqeust的消息,要求其他的主節點給自己投票
其他收到主節點並且還沒投票的情況下會把票投給他,返回一個cluster_type_fallover_auth_ack的消息,就是欽定他
當集群中n/2+1的數量的投票從就成為主。
這個選舉周期沒選成,就下一個周期重新開始
對比
安裝redis 需要注意的幾個參數
系統參數
vm.overcommit_memory = 1
net.core.somaxconn = 8192 同配置的backlog
echo never > /sys/kernel/mm/transparent_hugepage/enabled
配置參數
Maxmemory 102400mb/10gb
timeout 180
tcp-keepalive 300
repl-backlog-size 32M #psync初始大小
client-output-buffer-limit normal 512mb 256mb 60
client-output-buffer-limit slave 1024mb 256mb 120