深入瞭解node​中怎麼使用redis叢集功能【設定詳解】

2022-03-30 22:01:24
node中怎麼使用redis叢集功能?下面本篇文章給大家詳解一下基於的redis叢集設定,希望對大家有所幫助!

關於中使用redis叢集功能,沒有找到一篇比較完整且通俗易懂的文章,因此自己在開發偵錯的過程中也走了不少彎路。

本文會詳細介紹了在本地如何搭建redis叢集、在使用者端如何使用叢集、在搭建過程中遇到的問題和錯誤彙總並說明,以避免下次使用的時候再走彎路,提高開發、工作效率。

使用叢集的背景是:在Redis單例模式下隨著使用者量、存取量的提高,qps值急劇上漲??,大量的io操作導致某一時刻佔滿cpu(100%),隨時有宕機的危險,同時通過批次處理redis等方式也是治標不治本,無法突破伺服器效能的瓶頸。因此使用叢集方案或增加redis範例就勢在必行。

名詞解釋--叢集

叢集一般是指伺服器叢集,區別於分散式系統,是將很多伺服器集中起來一起進行同一種服務,在使用者端看來就像是隻有一個伺服器。叢集可以利用多個計算機進行平行計算從而獲得很高的計算速度,也可以用多個計算機做備份,從而使得任何一個機器壞了整個系統還是能正常執行。(在redis3.0之前一般使用的都是 哨兵模式,但 哨兵的設定略微複雜,並且效能和高可用性等各方面表現一般)

redis叢集要求

由於投票容錯機制要求超過半數節點認為某個節點掛了該節點才是掛了,所以2個節點無法構成叢集,因此Redis叢集至少需要3個節點。

要保證叢集的高可用、需要每個節點都有從節點(也就是備份節點),所以Redis叢集至少需要6臺伺服器。 (三主三從、三存三取、高可用、可備份)

當然,我們在本地偵錯時不可能用這麼多伺服器,因此我們可以在本地模擬執行6個redis範例,事實上生產環境的Redis叢集搭建和這裡基本上一樣。

mac 環境下搭建本地redis叢集

1. 下載安裝redis

可以在官網選擇安裝,也可以用命名行安裝

#安裝
brew install redis
#啟動
redis-server
#進入redis使用者端
redis-cli

2. 通過redis設定叢集環境

首先要找到redis組態檔的位置

  • brew list redis # 檢視redis安裝的位置
  • cd /opt/homebrew/Cellar/redis/6.2.4 # 根據位置進入版本號所在的資料夾
  • open . # 開啟資料夾
  • Xcode.app開啟homebrew.mxcl.redis.plist, 即可找到redis.conf所在的位置,如下所示:

1.png

2.png

建立六個服務組態檔

cd /opt/homebrew/etc/(上一步找到的組態檔目錄)

# 需要在 /opt/homebrew/etc/ 路徑下
mkdir -p redis/cluster/7000
mkdir -p redis/cluster/7001
mkdir -p redis/cluster/7002
mkdir -p redis/cluster/7003
mkdir -p redis/cluster/7004
mkdir -p redis/cluster/7005

修改組態檔

/opt/homebrew/etc/redis.conf路徑下的組態檔不用去修改, 只要將其copy到上面建立的 redis/cluster/7000目錄下,然後再修改,步驟如下

  • 先複製一份組態檔修改
cd /opt/homebrew/etc/ # 進入組態檔目錄
cp redis.conf redis/cluster/7000/7000.conf
code redis/cluster/7000/7000.conf # 用編輯器開啟或者用vim開啟組態檔來進行修改
  • 進入到7000.conf後,修改以下屬性
# Redis埠號(7000-7005每個組態檔都要修改)
port 7000  

# 開啟叢集模式執行
cluster-enabled yes   

# 叢集內部組態檔組態檔路徑,預設nodes-6379.conf(7000-7005每個組態檔都要修改)
cluster-config-file nodes-7000.conf 

# 節點間通訊的超時時間
cluster-node-timeout 5000  

# 資料持久化
appendonly yes
  • 將7000.conf複製到每個redis服務的目錄下
cd /opt/homebrew/etc/redis/cluster # 進入組態檔目錄

cp 7000/7000.conf 7001/7001.conf
cp 7000/7000.conf 7002/7002.conf
cp 7000/7000.conf 7003/7003.conf
cp 7000/7000.conf 7004/7004.conf
cp 7000/7000.conf 7005/7005.conf
  • 再修改7001.conf-7005.conf每個組態檔的port和cluster-config-file屬性

注意:每個組態檔必需設定不一樣的port和cluster-config-file值(否則叢集不會生效),上面是以埠區分。

通過find /opt/homebrew -name nodes-7000.conf命令可查詢到該組態檔的目錄


3. 啟動和停止叢集服務

由於我們設定了6個服務,因此不可能一個一個的啟動或停止,需要藉助shell指令碼來實現

進入/opt/homebrew/etc/redis/cluster目錄,建立start.sh和stop.sh檔案

# start.sh 檔案
#!/bin/sh
redis-server /opt/homebrew/etc/redis/cluster/7000/7000.conf &
redis-server /opt/homebrew/etc/redis/cluster/7001/7001.conf &
redis-server /opt/homebrew/etc/redis/cluster/7002/7002.conf &
redis-server /opt/homebrew/etc/redis/cluster/7003/7003.conf &
redis-server /opt/homebrew/etc/redis/cluster/7004/7004.conf &
redis-server /opt/homebrew/etc/redis/cluster/7005/7005.conf &

# stop.sh 檔案
#!/bin/sh
redis-cli -p 7000 shutdown &
redis-cli -p 7001 shutdown &
redis-cli -p 7002 shutdown &
redis-cli -p 7003 shutdown &
redis-cli -p 7004 shutdown &
redis-cli -p 7005 shutdown &

執行./start.sh或者./stop.sh來啟停服務

執行ps -ef |grep redis來檢視已啟動的redis服務

注意: 第一次執行./start.sh需要通過sudo chmod +x start.sh授權執行許可權

4. 相關命令

redis-cli -p 7000 # 單個使用者端啟動
redis-server 7000/7000.conf  # 啟動單個伺服器端
redis-cli -p 7000 shutdown # 關閉伺服器端
sudo chmod +x start.sh # 開啟指令碼執行許可權

# 設定redis主從關係(三主三從)
redis-cli --cluster create  --cluster-replicas 1 127.0.0.1:7000 127.0.0.1:7001 127.0.0.1:7002 127.0.0.1:7003 127.0.0.1:7004 127.0.0.1:7005

cluster nodes #檢視叢集節點情況(進入某個使用者端執行)
cluster info #檢視叢集資訊(進入某個使用者端執行)

檢視所有key值:keys *

刪除指定索引的值:del key

清空整個 Redis 伺服器的資料:flushall 

清空當前庫中的所有 key:flushdb

使用者端使用 ioredis 框架接入叢集

Redis.Cluster提供了在多個Redis節點上自動分片的功能,使用前面搭建好的六個redis伺服器,然後在本地啟動node redis.js,就可以測試叢集的效果了。ioredis

// redis.js
const Redis = require("ioredis");

const cluster = new Redis.Cluster([
  {
    port: 7000,
    host: "127.0.0.1",
  },
  {
    port: 7001,
    host: "127.0.0.1",
  },
]);

cluster.set("foo", "bar");
cluster.get("foo", (err, res) => {
  // res === 'bar'
});

使用bull框架(redis 佇列)

import Queue from 'bull'
// 建立redis佇列範例
const instance = new Queue('custom', {
  prefix : '{myprefix}',
  createClient(type) {
    // cluster 叢集範例同上
    return cluster
  }
})

// 新增資料到redis佇列(生產者)
instance.add(
  'request', 
  { 
    ...params
  },
  {
    removeOnComplete: false
  }
).catch(e => {
  console.error(e)
})

// 消費者回撥
instance.process('request', 5, async (job, done) => {
  console.log('獲取當前消費的資料:', job.data)
  // 執行非同步操作
  await new Promise((resolve)=>resolve())
  done()
})

使用bull框架連線ioredis叢集時存在問題: 每次有資料pushredis佇列時對應的回撥函數可能會觸發多次,目前無法確定是使用的問題還是框架本身的問題(如果有了解的歡迎大家留言告知)。

替代叢集的方案:在不需要資料同步和資料遷移的情況下,可以在使用者端使用多個redis範例,結合Math.random()使資料平分到其中的一個redis,從而解決了單個範例硬體(cpu等)瓶頸的問題。

問題處理

1、Mac系統下連線redis報錯?

控制檯錯誤提示:Could not connect to Redis at 127.0.0.1:6379: Connection refused

原因:伺服器端沒有開啟或啟動失敗

解決辦法:需要先啟動redis伺服器端redis-server

參考連結

https://blog.csdn.net/qq_23347459/article/details/104257529

2、使用者端啟動、讀寫報錯?

錯誤提示:ClusterAllFailedError: Failed to refresh slots cache.

原因:每個服務下的組態檔中的cluster-config-file屬性一致。

處理:修改成唯一的屬性值

  • 參考連結1

    https://stackoverflow.com/questions/57350961/ioredis-clusterallfailederror-failed-to-refresh-slots-cache

  • 參考2

    https://github.com/luin/ioredis/issues/711

3、執行建立主從redis語句失敗?

執行語句:redis-cli --cluster create --cluster-replicas 1 127.0.0.1:7000 127.0.0.1:7001 127.0.0.1:7002 127.0.0.1:7003 127.0.0.1:7004 127.0.0.1:7005

提示錯誤:[ERR] Node 127.0.0.1:7000 is not empty. Either the node already knows other nodes (check with CLUSTER NODES) or contains some key in database 0

原因:執行建立語句時,沒有清空資料和重置叢集

處理:清空資料和重置叢集, 清除rdb和aof檔案

參考清除redis資料

https://stackoverflow.com/questions/37206993/redis-server-cluster-not-working

# 以7000埠的服務為例,7001-7005重複以下操作
$redis-cli -p 7000
127.0.0.1:7000> flushall
127.0.0.1:7000> cluster reset
127.0.0.1:7000> exit

# 使用find找到rdb和aof檔案(也在rdb目錄下)
find /opt/homebrew -name dump.rdb

# 重新執行建立語句成功
redis-cli --cluster create  --cluster-replicas 1 127.0.0.1:7000 127.0.0.1:7001 127.0.0.1:7002 127.0.0.1:7003 127.0.0.1:7004 127.0.0.1:7005

結語

redis叢集在使用者端的使用是非常簡單的,相比之下伺服器端的設定會比較繁瑣。

使用者端的具體使用只做了一下簡單的說明,使用過程中要注意redis資料的同步和遷移等問題。

使用叢集雖然能提升服務能力、支援主從複製、哨兵模式、讀寫分離、平分伺服器的壓力等特點。但不具備自動容錯和恢復功能,如果出現宕機會使部分讀寫請求失敗,降低了系統的可用性。在使用時根據業務情況分析、選擇不同的方案。

本文轉載自:https://juejin.cn/post/7079928963107127327

作者:tager

更多node相關知識,請存取:!

以上就是深入瞭解node​中怎麼使用redis叢集功能【設定詳解】的詳細內容,更多請關注TW511.COM其它相關文章!