redis分散式叢集建置介紹
Redis叢集架構圖
#上圖藍色為redis集群的節點。
節點之間透過ping指令來測試連線是否正常,節點之間沒有主區分,當連接到任何一個節點進行操作時,都可能會轉送到其他節點。
1、Redis的容錯機制
節點之間會定時的互相發送ping指令,測試節點的健康狀態,當節點接受到ping指令後,會傳回一個pong字串。
投票機制:如果一個節點A給節點B發送ping沒有得到pong返回,會通知其他節點再次給B發送ping,如果集群中有超過一半的節點收不B節點的pong。那就認為B節點掛了。一般會為每個節點提供一個備份節點,如果掛掉會切換到備份節點。
2、Redis叢集儲存原理
Redis對於每個存放的key會進行hash操作,產生一個[0-16384]的hash值(先進行
crc 演算法再對16384取餘)。
集群的情況下,就是把[0-16384]的區間進行拆分,放到不同的redis中。
3、Redis的持久化
Snapshotting:定時的將Redis記憶體中的資料保存到硬碟中
AOF:將所有的command操作保存到aof中,AOP的同步頻率很高,資料即使遺失,粒度也很小,但會在效能上造成影響。
二、叢集環境建置
#redis叢集管理工具redis-trib.rb依賴ruby環境,首先需要安裝ruby環境
安裝ruby
yum install ruby yum install rubygems
安裝ruby和redis的介面程式
拷貝redis-3.0.0.gem至/usr/local下
執行:
gem install /usr/local/redis-3.0.0.gem
三、建立Redis叢集
在一台伺服器上,可以用不同連接埠號來表示不同redis伺服器。
Redis叢集最少需要三台伺服器,而每台伺服器有需要備用伺服器,所以最少需要6台伺服器。連接埠規劃如下:
主伺服器:192.168.100.66 :7001 :7002 :7003
從伺服器:192.168.100.66 :7004 :7005 168.100.66 :7004 :7005 168.100.66 :7004 :7005 106/#o#o#o#-#>70#>702/#> local 創建文件夾用來存放服務器程序
mkdir 7001 7002 7003 7004 7005 7006
如果想讓redis支持集群需要修改redis.config配置文件的cluster-enabled yes
本例中我們以連接埠來區別不同的redis服務,所以還需要修改redis.config的port為對應埠
修改完設定文件,將redis安裝目錄的bin複製到上面每個目錄中。
分別進入7001/bin/ 7002/bin .....
啟動服務./redis-server ./redis.conf
查看redis進程:ps - aux|grep redis 如下圖說明啟動成功
建立叢集:
將先前解壓縮的資料夾的redis-3.0.0/src/redis -trib.rb複製到redis-cluster目錄
運行
./redis-trib.rb create --replicas 1 192.168.100.66:7001 192.168.100.66:7002 192.168.100.66:7003 192.168.100.66:7004 192.168.100.66:7005 192.168.100.66:7006
如果執行時報如下錯誤:
[ERR] Node XXXXXX is not empty. Either the node already knows other nodes (check with CLUSTER NODES) or contains some key in database 0
解決方法是刪除產生的設定檔nodes.conf,如果不行則說明現在創建的結點包括了舊集群的結點信息,需要刪除redis的持久化文件後再重啟redis,比如:appendonly.aof、dump.rdb
如果成功最終輸入如下:
查詢叢集資訊:
#說明:
./redis-cli -c - h 192.168.101.3 -p 7001 ,其中-c表示以叢集方式連接redis,-h指定ip位址,-p指定連接埠號碼
cluster nodes 查詢叢集結點資訊
cluster info查詢叢集狀態資訊
第一步:連線上叢集
./ redis-trib.rb reshard 192.168.101.3:7001(連接群集中任一可用結點都行)
第二步:輸入要指派的槽數
#輸入 500表示要分配500個槽
第三個步驟:輸入接收槽的結點id
这里准备给7007分配槽,通过cluster nodes查看7007结点id为15b809eadae88955e36bcdbb8144f61bbbaf38fb
输入:15b809eadae88955e36bcdbb8144f61bbbaf38fb
第四步:输入源结点id
这里输入all
第五步:输入yes开始移动槽到目标结点id
添加从节点
集群创建成功后可以向集群中添加节点,下面是添加一个slave从节点。
添加7008从结点,将7008作为7007的从结点。
./redis-trib.rb add-node --slave --master-id 主节点id 添加节点的ip和端口 集群中已存在节点ip和端口
执行如下命令:
./redis-trib.rb add-node --slave --master-id cad9f7413ec6842c971dbcc2c48b4ca959eb5db4 192.168.101.3:7008 192.168.101.3:7001
cad9f7413ec6842c971dbcc2c48b4ca959eb5db4 是7007结点的id,可通过cluster nodes查看。
注意:如果原来该结点在集群中的配置信息已经生成cluster-config-file指定的配置文件中(如果cluster-config-file没有指定则默认为nodes.conf),这时可能会报错:
[ERR] Node XXXXXX is not empty. Either the node already knows other nodes (check with CLUSTER NODES) or contains some key in database 0
解决方法是删除生成的配置文件nodes.conf,删除后再执行./redis-trib.rb add-node指令
查看集群中的结点,刚添加的7008为7007的从节点:
删除结点:
./redis-trib.rb del-node 127.0.0.1:7005 4b45eb75c8b428fbd77ab979b85080146a9bc017
删除已经占有hash槽的结点会失败,报错如下:
[ERR] Node 127.0.0.1:7005 is not empty! Reshard data away and try again.
需要将该结点占用的hash槽分配出去(参考hash槽重新分配章节)。
测试:
Maven: <dependencies> <dependency> <groupId>redis.clients</groupId> <artifactId>jedis</artifactId> <version>2.7.0</version> </dependency> <!-- https://mvnrepository.com/artifact/junit/junit --> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.12</version> <scope>test</scope> </dependency> <!-- https://mvnrepository.com/artifact/org.springframework/spring-test --> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-test</artifactId> <version>4.3.10.RELEASE</version> <scope>test</scope> </dependency> </dependencies>
普通测试:
@Test public void redisClusterTest1(){ JedisPoolConfig config=new JedisPoolConfig(); config.setMaxTotal(30); config.setMaxIdle(2); Set<HostAndPort> jedisNode=new HashSet<HostAndPort>(); jedisNode.add(new HostAndPort("192.168.100.66",7001)); jedisNode.add(new HostAndPort("192.168.100.66",7002)); jedisNode.add(new HostAndPort("192.168.100.66",7003)); jedisNode.add(new HostAndPort("192.168.100.66",7004)); jedisNode.add(new HostAndPort("192.168.100.66",7005)); jedisNode.add(new HostAndPort("192.168.100.66",7006)); JedisCluster jc=new JedisCluster(jedisNode,config); jc.set("name","老王"); String value=jc.get("name"); System.out.println(value); }
Spring测试:
配置文件:
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"> <!-- 连接池配置 --> <bean id="jedisPoolConfig" class="redis.clients.jedis.JedisPoolConfig"> <!-- 最大连接数 --> <property name="maxTotal" value="30" /> <!-- 最大空闲连接数 --> <property name="maxIdle" value="10" /> <!-- 每次释放连接的最大数目 --> <property name="numTestsPerEvictionRun" value="1024" /> <!-- 释放连接的扫描间隔(毫秒) --> <property name="timeBetweenEvictionRunsMillis" value="30000" /> <!-- 连接最小空闲时间 --> <property name="minEvictableIdleTimeMillis" value="1800000" /> <!-- 连接空闲多久后释放, 当空闲时间>该值 且 空闲连接>最大空闲连接数 时直接释放 --> <property name="softMinEvictableIdleTimeMillis" value="10000" /> <!-- 获取连接时的最大等待毫秒数,小于零:阻塞不确定的时间,默认-1 --> <property name="maxWaitMillis" value="1500" /> <!-- 在获取连接的时候检查有效性, 默认false --> <property name="testOnBorrow" value="true" /> <!-- 在空闲时检查有效性, 默认false --> <property name="testWhileIdle" value="true" /> <!-- 连接耗尽时是否阻塞, false报异常,ture阻塞直到超时, 默认true --> <property name="blockWhenExhausted" value="false" /> </bean> <!-- redis集群 --> <bean id="jedisCluster" class="redis.clients.jedis.JedisCluster"> <constructor-arg index="0"> <set> <bean class="redis.clients.jedis.HostAndPort"> <constructor-arg index="0" value="192.168.100.66"></constructor-arg> <constructor-arg index="1" value="7001"></constructor-arg> </bean> <bean class="redis.clients.jedis.HostAndPort"> <constructor-arg index="0" value="192.168.100.66"></constructor-arg> <constructor-arg index="1" value="7002"></constructor-arg> </bean> <bean class="redis.clients.jedis.HostAndPort"> <constructor-arg index="0" value="192.168.100.66"></constructor-arg> <constructor-arg index="1" value="7003"></constructor-arg> </bean> <bean class="redis.clients.jedis.HostAndPort"> <constructor-arg index="0" value="192.168.100.66"></constructor-arg> <constructor-arg index="1" value="7004"></constructor-arg> </bean> <bean class="redis.clients.jedis.HostAndPort"> <constructor-arg index="0" value="192.168.100.66"></constructor-arg> <constructor-arg index="1" value="7005"></constructor-arg> </bean> <bean class="redis.clients.jedis.HostAndPort"> <constructor-arg index="0" value="192.168.100.66"></constructor-arg> <constructor-arg index="1" value="7006"></constructor-arg> </bean> </set> </constructor-arg> <constructor-arg index="1" ref="jedisPoolConfig"></constructor-arg> </bean> </beans>
测试类:
@RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration({"classpath:spring-config.xml"}) public class RedisClusterTest { @Autowired private JedisCluster jedisCluster; @Test public void redisClusterTest2(){ jedisCluster.set("username","小明啦啦"); String name=jedisCluster.get("username"); System.out.println(name); } }
更多redis知识请关注redis数据库教程栏目。
以上是redis分散式叢集建置介紹的詳細內容。更多資訊請關注PHP中文網其他相關文章!

熱AI工具

Undresser.AI Undress
人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover
用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool
免費脫衣圖片

Clothoff.io
AI脫衣器

AI Hentai Generator
免費產生 AI 無盡。

熱門文章

熱工具

記事本++7.3.1
好用且免費的程式碼編輯器

SublimeText3漢化版
中文版,非常好用

禪工作室 13.0.1
強大的PHP整合開發環境

Dreamweaver CS6
視覺化網頁開發工具

SublimeText3 Mac版
神級程式碼編輯軟體(SublimeText3)

熱門話題

Redis集群模式通過分片將Redis實例部署到多個服務器,提高可擴展性和可用性。搭建步驟如下:創建奇數個Redis實例,端口不同;創建3個sentinel實例,監控Redis實例並進行故障轉移;配置sentinel配置文件,添加監控Redis實例信息和故障轉移設置;配置Redis實例配置文件,啟用集群模式並指定集群信息文件路徑;創建nodes.conf文件,包含各Redis實例的信息;啟動集群,執行create命令創建集群並指定副本數量;登錄集群執行CLUSTER INFO命令驗證集群狀態;使

使用 Redis 指令需要以下步驟:打開 Redis 客戶端。輸入指令(動詞 鍵 值)。提供所需參數(因指令而異)。按 Enter 執行指令。 Redis 返迴響應,指示操作結果(通常為 OK 或 -ERR)。

啟動 Redis 服務器的步驟包括:根據操作系統安裝 Redis。通過 redis-server(Linux/macOS)或 redis-server.exe(Windows)啟動 Redis 服務。使用 redis-cli ping(Linux/macOS)或 redis-cli.exe ping(Windows)命令檢查服務狀態。使用 Redis 客戶端,如 redis-cli、Python 或 Node.js,訪問服務器。

理解 Redis 源碼的最佳方法是逐步進行:熟悉 Redis 基礎知識。選擇一個特定的模塊或功能作為起點。從模塊或功能的入口點開始,逐行查看代碼。通過函數調用鏈查看代碼。熟悉 Redis 使用的底層數據結構。識別 Redis 使用的算法。

使用Redis進行鎖操作需要通過SETNX命令獲取鎖,然後使用EXPIRE命令設置過期時間。具體步驟為:(1) 使用SETNX命令嘗試設置一個鍵值對;(2) 使用EXPIRE命令為鎖設置過期時間;(3) 當不再需要鎖時,使用DEL命令刪除該鎖。

解決redis-server找不到問題的步驟:檢查安裝,確保已正確安裝Redis;設置環境變量REDIS_HOST和REDIS_PORT;啟動Redis服務器redis-server;檢查服務器是否運行redis-cli ping。

Redis 使用哈希表存儲數據,支持字符串、列表、哈希表、集合和有序集合等數據結構。 Redis 通過快照 (RDB) 和追加只寫 (AOF) 機制持久化數據。 Redis 使用主從復制來提高數據可用性。 Redis 使用單線程事件循環處理連接和命令,保證數據原子性和一致性。 Redis 為鍵設置過期時間,並使用 lazy 刪除機制刪除過期鍵。

要從 Redis 讀取隊列,需要獲取隊列名稱、使用 LPOP 命令讀取元素,並處理空隊列。具體步驟如下:獲取隊列名稱:以 "queue:" 前綴命名,如 "queue:my-queue"。使用 LPOP 命令:從隊列頭部彈出元素並返回其值,如 LPOP queue:my-queue。處理空隊列:如果隊列為空,LPOP 返回 nil,可先檢查隊列是否存在再讀取元素。
