redis-集群分片
Redis 分區
??分區是分割數據到多個Redis實例的處理過程,因此每個實例只保存key的一個子集。
分區的優勢
??1.通過利用多臺計算機內存的和值,允許我們構造更大的數據庫。
??2.通過多核和多臺計算機,允許我們擴展計算能力;通過多臺計算機和網絡適配器,允許我們擴展網絡帶寬。
分區的不足
??1.redis的一些特性在分區方面表現的不是很好:
??2.涉及多個key的操作通常是不被支持的。舉例來說,當兩個set映射到不同的redis實例上時,你就不能對這兩個set執行交集操作。
??3.涉及多個key的redis事務不能使用。
??4.當使用分區時,數據處理較為復雜,比如你需要處理多個rdb/aof文件,并且從多個實例和主機備份持久化文件。
??5.增加或刪除容量也比較復雜。redis集群大多數支持在運行時增加、刪除節點的透明數據平衡的能力,但是類似于客戶端分區、代理等其他系統則不支持這項特性。然而,一種叫做presharding的技術對此是有幫助的。
?
分區類型
??1.范圍分區:最簡單的分區方式是按范圍分區,就是映射一定范圍的對象到特定的Redis實例,比如,ID從0到10000的用戶會保存到實例R0,ID從10001到 20000的用戶會保存到R1,以此類推。
??2.哈希分區:另外一種分區方法是hash分區。這對任何key都適用,也無需是object_name:這種形式,像下面描述的一樣簡單:用一個hash函數將key轉換為一個數字,比如使用crc32 hash函數。對key foobar執行crc32(foobar)會輸出類似93024922的整數。對這個整數取模,將其轉化為0-3之間的數字,就可以將這個整數映射到4個Redis實例中的一個了。93024922 % 4 = 2,就是說key foobar應該被存到R2實例中。注意:取模操作是取除的余數,通常在多種編程語言中用%操作符實現。
?
下面我嘗試在本機(mac,其他系統思路一樣)上開啟3個redis-service來模擬多機器環境。
??1.去官網( https://redis.io/download )上把redis下載了
??2.解壓之后切cd到第一層目錄之后 執行 mark install
??3.把redis.conf文件找到,在第一層目錄下
??4.執行上面之后就能在src文件夾下找到redis-cli和redis-server其他的文件都不用
??5.ok 目前是這三個文件 redis-serve/redis-cli/redis.conf
??6.現在模擬三個機器(端口6379/6380/6381),只要對應制作三個redis.conf就行,以redis.conf為基礎模板改??
??7.改三個地方(其他部分別動,用redis.conf當模板),得到如下三個配置文件
?
??redis6379.conf
????port 6379
????pidfile /var/run/redis_6379.pid
????dbfilename dump-6379.rdb
??redis6380.conf
????port 6380
????pidfile /var/run/redis_6380.pid
????dbfilename dump-6380.rdb
??redis6381.conf
????port 6381
????pidfile /var/run/redis_6381.pid
????dbfilename dump-6381.rdb
?
??8.嘗試把這三個redis-service 啟動起來
????redis-server redis6379.conf
????redis-server redis6380.conf
????redis-server redis6381.conf
??
??9.ps -a | grep redis-server 產看啟動結果,如下:
????1892 ttys001 ???0:03.28 redis-server 127.0.0.1:6381
????1863 ttys003 ???0:03.74 redis-server 127.0.0.1:6379
????1864 ttys004 ???0:04.01 redis-server 127.0.0.1:6380
?
然后是開始分片測試,java的話直接用 JedisShardInfo/ShardedJedisPool 就行,我是用的node,但是沒找到相關的庫,我手寫了下,代碼如下:
//npm install redis const redis = require("redis");//開3個redis節點,可以在一個服務器上,也可以分散多個服務器 //PS:如果是自己搭建集群,可以直接一個節點,指向負載均衡的節點上 const client_machine0 = redis.createClient(6379); const client_machine1 = redis.createClient(6380); const client_machine2 = redis.createClient(6381); //造999個用戶請求出來 const quaryCount = 999; let cacheDatas = []; for (let index = 0; index < quaryCount; index++) { const nowData = { userId: index, cacheKey: 'k' + index, cacheValue: 'v' + index } cacheDatas.push(nowData); } //分片算法,主流式根據id分區域或者key hash出來 //我這按照id然后mod服務器個數做的 //這里可以自定義算法,一是考慮負載均衡,而是考慮擴展,三是考慮machine死掉怎么救 //運行起來的服務,如果要臨時更改,一定一定一定要考慮周全。 //PS:如果是集群的話,這部分邏輯是需要寫在集群里,使用者只是訪問唯一的地址(通常是某個負載均衡地址)const getMachine = (quaryData) => { let redisMachine = null; switch (quaryData.userId % 3) { case 0: redisMachine = client_machine0; break; case 1: redisMachine = client_machine1; break; case 2: redisMachine = client_machine2; break; default: break; } return redisMachine; }//開始請求模擬 for (let index = 1; index < quaryCount; index++) { const cacheData = cacheDatas[index]; const machine = getMachine(cacheData); if(!machine){ console.log('Error: not find machine!!!'); }else{ machine.set(cacheData.cacheKey, cacheData.cacheValue, redis.print); } }//關閉所有連接 client_machine0.quit(); client_machine1.quit(); client_machine2.quit();關于在線擴容:Redis的作者提出了一種叫做presharding
??1.在新機器上啟動好對應端口的Redis實例。
??2.配置新端口為待遷移端口的從庫。
??3.待復制完成,與主庫完成同步后,切換所有客戶端配置到新的從庫的端口。
??4.配置從庫為新的主庫。
??5.移除老的端口實例。
??6.重復上述過程遷移好所有的端口到指定服務器上。
?
增加高可用的思路就是主從復制
基本命令
??成為別人的從庫: SLAVEOF host port
??取消成為別人的從庫 ?SLAVEOF NO ONE
主從配置更詳細的解釋跟更多細節,看下這個:
https://www.jianshu.com/p/ba3cc187da9c
?
?
總結
以上是生活随笔為你收集整理的redis-集群分片的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 区分docker stack/servi
- 下一篇: Docker 集群 图形化显示 Visu