노드에서 Redis 클러스터 기능을 어떻게 사용하나요? 다음 글에서는 node 기반의 Redis 클러스터 구성에 대해 자세히 설명하겠습니다. 도움이 되셨으면 좋겠습니다!
nodejs
nodejs
中使用redis
集群功能,没有找到一篇比较完整且通俗易懂的文章,因此自己在开发调试的过程中也走了不少弯路。
本文会详细介绍了在本地如何搭建redis集群、在客户端如何使用集群、在搭建过程中遇到的问题和错误汇总并说明,以避免下次使用的时候再走弯路,提高开发、工作效率。
使用集群的背景是:在Redis单例模式下随着用户量、访问量的提高,qps值急剧上涨??,大量的io
操作导致某一时刻占满cpu(100%)
,随时有宕机的危险,同时通过批量处理redis等方式也是治标不治本,无法突破服务器性能的瓶颈。因此使用集群方案或增加redis实例就势在必行。
集群一般是指服务器集群,区别于分布式系统,是将很多服务器集中起来一起进行同一种服务,在客户端看来就像是只有一个服务器。集群可以利用多个计算机进行并行计算从而获得很高的计算速度,也可以用多个计算机做备份,从而使得任何一个机器坏了整个系统还是能正常运行。(在redis3.0之前一般使用的都是 哨兵模式,但 哨兵的配置略微复杂,并且性能和高可用性等各方面表现一般)
由于投票容错机制要求超过半数节点认为某个节点挂了该节点才是挂了,所以2个节点无法构成集群,因此Redis集群至少需要3个节点。
要保证集群的高可用、需要每个节点都有从节点(也就是备份节点),所以Redis
集群至少需要6台服务器。 (三主三从、三存三取、高可用、可备份)
当然,我们在本地调试时不可能用这么多服务器,因此我们可以在本地模拟运行6个redis
实例,事实上生产环境的Redis集群搭建和这里基本上一样。
可以在官网选择安装,也可以用命名行安装
#安装 brew install redis #启动 redis-server #进入redis客户端 redis-cli
首先要找到redis配置文件的位置
brew list redis
# 查看redis安装的位置cd /opt/homebrew/Cellar/redis/6.2.4
# 根据位置进入版本号所在的文件夹open .
# 打开文件夹Xcode.app
打开homebrew.mxcl.redis.plist
, 即可找到redis.conf
所在的位置,如下所示:创建六个服务配置文件
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
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
의 redis
클러스터 기능 사용과 관련하여 비교적 완전하고 이해하기 쉬운 글을 찾지 못해서 여기에 있습니다. 개발과 디버깅 과정에서도 우회를 많이 했습니다. 이 글에서는
io
작업으로 인해 특정 순간에 가 가득 차면 >cpu(100%)
, 언제든지 다운타임이 발생할 위험이 있습니다. 동시에 redis 및 기타 방법의 일괄 처리는 증상만 치료할 뿐, 그렇지 않습니다. 근본 원인을 해결하고, 서버 성능의 병목 현상을 돌파할 수 없습니다. 따라서 클러스터 솔루션을 사용하거나 Redis 인스턴스를 추가하는 것이 필수적입니다. 클러스터는 일반적으로 서버 클러스터를 말하며, 분산 시스템과 달리 여러 개의 서버가 모여 있는 그룹입니다. 동일한 서비스를 제공하기 위해 함께 제공되는 서버는 하나인 것 같습니다. 클러스터는 병렬 컴퓨팅
높은 컴퓨팅 속도를 달성하려면 여러 대의 컴퓨터를 사용할 수도 있습니다 Backup🎜, 그러면 기계가 고장나도 전체 시스템이 계속 정상적으로 작동할 수 있습니다. (🎜redis3.0 이전에는 🎜 🎜Sentinel 모드를 많이 사용했지만 🎜 🎜Sentinel의 구성은 다소 복잡하고 성능이나 고가용성은 모든 면에서 평균 수준입니다 🎜)🎜Redis
클러스터에는 최소 6개의 서버가 필요합니다. 🎜(3개의 마스터와 3개의 슬레이브, 3개의 입금과 3개의 검색, 고가용성, 백업)🎜🎜🎜물론 로컬에서 디버깅할 때 너무 많은 서버를 사용하는 것은 불가능하므로 6개의 redis예제, 🎜사실 프로덕션 환경의 Redis 클러스터 설정은 기본적으로 여기와 같습니다. 🎜🎜<h2 data-id="heading-3">Mac 환경에서 로컬 Redis 클러스터 구축</h2>
<h3 data-id="heading-4">🎜1 redis를 다운로드하고 설치할 수 있습니다🎜🎜🎜 공식 웹사이트에서 설치를 선택하고 명명된 라인을 사용하여 install🎜<pre class="brush:js;toolbar:false;"># 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 &</pre><h3 data-id="heading-5">🎜2할 수도 있습니다. redis🎜🎜🎜🎜를 통해 클러스터 환경을 구성합니다. redis 구성 파일🎜🎜<ul>
<li> <code>brew list redis
# redis 설치 위치 확인
cd /opt/homebrew/Cellar/redis/6.2. 4
# 위치에 따라 버전 번호를 입력하세요. 폴더open .
# 폴더 열기Xcode.app를 사용하여 <code>homebrew.mxcl.redis .plist
를 열면 아래와 같이 redis.conf
의 위치를 찾을 수 있습니다. cd /opt/homebrew/ etc/
(이전 단계에서 찾은 구성 파일 디렉터리)🎜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🎜🎜구성 파일을 수정하세요🎜🎜🎜
/경로 아래의 구성 파일 opt/homebrew/etc/redis.conf
는 수정할 필요가 없으며, 위에서 생성한 redis/cluster/7000
디렉터리에 복사한 후 수정하면 됩니다. 다음과 같습니다🎜// 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' });
7000.conf
입력 후 다음 속성을 수정하세요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() })
# 以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
7001.conf-7005를 수정합니다. conf
각 구성 파일의 포트 및 클러스터 구성 파일 속성port 및 Cluster-config-file
값을 사용합니다(그렇지 않으면 클러스터가 적용되지 않습니다). 🎜🎜🎜 🎜find /opt/homebrew -namenodes-7000.conf
🎜 명령🎜🎜🎜🎜🎜3을 통해 구성 파일의 디렉터리를 찾을 수 있습니다🎜. 🎜🎜6개의 서비스를 구성했기 때문에 하나씩 시작하거나 중지하는 것은 불가능합니다. 이를 위해서는 쉘 스크립트를 사용해야 합니다🎜进入/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
授权执行权限
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
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' });
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
集群时存在问题: 每次有数据push
到redis
队列时对应的回调函数可能会触发多次,目前无法确定是使用的问题还是框架本身的问题(如果有了解的欢迎大家留言告知)。
替代集群的方案:在不需要数据同步和数据迁移的情况下,可以在客户端使用多个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相关知识,请访问:nodejs 教程!
위 내용은 노드에서 redis 클러스터 기능을 사용하는 방법 자세히 알아보기 [세부 구성]의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!