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

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章