Redis 主從集羣以及對等節點集羣搭建以及連接
前言
Redis是開源的,內存數據結構存儲的健值數據庫。用於數據存儲,緩存和消息代理。支持的數據結構有字符串,Hash,List,Set,有序集合等等。除此之外,Redis還使用集羣來提供高可用性。本文就介紹如何搭建Redis主從集羣和Redis對等節點集羣。關於Redis的安裝部分,可以查看Redis在Window上的幾種安裝方法(包含linux)。廢話不多說,開始Redis集羣搭建之旅(通過端口號來搭建單機版的集羣)。
對等節點搭建(三節點)
集羣搭建基本命令:
./src/redis-cli --cluster create host1:port host2:port host3:port
- 首先在redis安裝目錄下新建cluster文件夾,然後在文件夾裏新建8001 8002 8003文件夾
mkdir cluster
cd cluster && mkdir 8001 8002 8003
- 在8001文件夾下新建redis.conf文件
vim redis.conf
,添加如下內容
port 8001 # 指定端口
cluster-enabled yes # 啓用集羣
cluster-config-file nodes-8001.conf # 文件名可以隨便起,但是不能重複
cluster-node-timeout 5000 # 指定超時時間
appendonly yes
- 將redis.conf分別複製到8002, 8003目錄中,並且將redis.conf文件裏面的8001分別改成8002和8003
cp redis.conf ../8002
cp redis.conf ../8003
- 分別啓動8001 8002 8003節點,在redis安裝目錄下分別執行以下命令
./src/redis-server cluster/8001/redis.conf
./src/redis-server cluster/8002/redis.conf
./src/redis-server cluster/8003/redis.conf
8001節點
8002節點
8003節點
- 搭建集羣,進入redis安裝目錄,使用如下命令
./src/redis-cli --cluster create 127.0.0.1:8001 127.0.0.1:8002 127.0.0.1:8003
等待分配slot,然後輸入yes即可,如下圖
使用客戶端連接集羣,Python和Java以及NodeJS
- Python,使用aredis包,代碼如下
import asyncio
from aredis import StrictRedisCluster
# 連接集羣
async def create_cluster(*ports: int):
nodes = list(
map(lambda port: {"host": "localhost", "port": port}, ports)
)
redis = StrictRedisCluster(startup_nodes = nodes)
await redis.flushdb()
return redis
async def main():
redis = await create_cluster(8001, 8002, 8003)
await redis.set("name", "sundial dreams")
print(await redis.get("name"))
if __name__ == "__main__":
asyncio.get_event_loop().run_until_complete(main())
- Java,使用lettuce包,代碼如下
package storm.Reactor;
import io.lettuce.core.RedisURI;
import io.lettuce.core.cluster.RedisClusterClient;
import io.lettuce.core.cluster.api.async.RedisClusterAsyncCommands;
import java.util.Arrays;
import java.util.List;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;
public class Cluster {
static private RedisClusterClient client;
static private RedisClusterAsyncCommands<String, String> createCluster(List<Integer> ports) {
List<RedisURI> redisURIS = ports.stream().map(
port -> RedisURI.builder().withHost("localhost").withPort(port).build()
).collect(Collectors.toList());
if (client == null) client = RedisClusterClient.create(redisURIS);
return client.connect().async(); // 使用異步命令
}
static public void main(String[] args) throws Exception {
RedisClusterAsyncCommands<String, String> async = createCluster(Arrays.asList(8001, 8002, 8003));
async.set("name", "sundial dreams").get(1, TimeUnit.MINUTES);
System.out.println(async.get("name").get(1, TimeUnit.MINUTES));
}
}
- Nodejs,使用ioredis包,代碼如下:
const Redis = require("ioredis");
async function main() {
const nodes = [8001, 8002, 8003].map(port => ({ host: "localhost", port }));
const cluster = new Redis.Cluster(nodes);
await cluster.set("name", "sundial dreams");
console.log(await cluster.get("name"));
/* or
cluster.set("name", "sundial dreams").then(() => {
cluster.get("name").then(console.log)
})
*/
}
main()
主從集羣搭建(一主三從三哨兵)
- 啓動主節點,以7000端口爲例,在redis安裝目錄下輸入如下命令
./src/redis-server --port 7000
通過指定–port參數來啓動,也可以將redis.conf的port改爲7000然後使用./src/redis-server redis.conf
來啓動
- 啓動三個從節點,分別運行在7004 7005 7006,任然使用指定端口的形式啓動,命令如下
./src/redis-server --port 7004
./src/redis-server --port 7005
./src/redis-server --port 7006
使用redis-cli來將三個從節點連接到主節點,./src/redis-cli -p port
連接對應端口,使用slaveof localhost 7000
來連接主節點
./src/redis-cli -p 7004
127.0.0.1:7004> slaveof localhost 7000
剩下的7005 7006操作步驟和上面一致,如下圖所示
在cli下可以使用info replication來查看節點信息
可以看到,節點7004的role(角色)已經變成slave(奴隸)節點了,然後主節點是7000。
- 啓動哨兵節點
- 首先新建sentinel文件夾,並在文件夾中新建sentinel1.conf文件
mkdir sentinel
cd sentinel && touch sentinel1.conf
編輯sentinel1.conf
port 26379
sentinel monitor mymaster 127.0.0.1 7000 2
將sentinel1.conf複製兩份,並更名爲sentinel2.conf和sentinel3.conf
cp sentinel1.conf sentinel2.conf
cp sentinel1.conf sentinel3.conf
將sentinel2.conf的port 修改爲26380,sentinel3.conf的port 修改爲26381
- 運行哨兵節點
./src/redis-server sentinel/sentinel1.conf --sentinel
./src/redis-server sentinel/sentinel2.conf --sentinel
./src/redis-server sentinel/sentinel3.conf --sentinel
26380哨兵節點
可以看到master節點爲7000,並且連接着的從節點(slave slave)有7006, 7005, 7004,然後哨兵節點(sentinel sentinel)有26380, 26379。到此爲止一主三從三哨兵的集羣搭建完成。
- 使用客戶端連接集羣,Java和NodeJS
- Java,使用luttuce包,連接代碼如下
package storm.Reactor;
import io.lettuce.core.RedisClient;
import io.lettuce.core.RedisURI;
import io.lettuce.core.api.async.RedisAsyncCommands;
import io.lettuce.core.cluster.RedisClusterClient;
import io.lettuce.core.cluster.api.async.RedisClusterAsyncCommands;
import java.util.List;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;
public class Cluster {
static private RedisClient redisClient;
// 連接一主三從三哨兵集羣
static private RedisAsyncCommands<String, String> createSentinel(RedisURI uri){
if (redisClient == null) redisClient = RedisClient.create(uri);
return redisClient.connect().async();
}
static public void main(String[] args) throws Exception {
RedisAsyncCommands<String, String> async = createSentinel(
RedisURI.builder().withSentinel("localhost", 26379)
.withSentinel("localhost", 26380)
.withSentinel("localhost", 26381)
.withSentinelMasterId("mymaster")
.build()
);
async.set("name", "sundial dreams").get(1, TimeUnit.MINUTES);
System.out.println(async.get("name").get(1, TimeUnit.MINUTES));
}
}
- NodeJS,使用ioredis包,代碼如下
const Redis = require("ioredis");
async function main() {
const sentinelNodes = [26379, 26380, 26381].map(port => ({ host: "localhost", port }));
const sentinel = new Redis({
sentinels: sentinelNodes,
name: "mymaster"
});
await sentinel.set("name", "sundial dreams");
console.log(await sentinel.get("name"));
/* or
sentinel.set("name", "dpf").then(() => {
sentinel.get("name").then(value => {
console.log(value)
})
})
*/
}
main()
本文主要介紹瞭如何使用redis(基於redis5)來搭建主從集羣和對等節點集羣,搭建步驟其實並不複雜,然後還順便介紹瞭如何使用python,java,nodejs來連接搭建的這兩類集羣。最後,如果讀者覺得這篇文章有幫助,別忘了點個贊哦。