搭建主从
version: "3"
networks:
redis-replication:
driver: bridge
ipam:
config:
- subnet: 172.25.0.0/24
services:
master:
image: 10.30.30.22:9080/library/redis:5.0.5
container_name: redis-master
ports:
- "6379:6379"
volumes:
- "./master/redis.conf:/etc/redis.conf"
- "./master/data:/data"
command: redis-server /etc/redis.conf
restart: always
networks:
redis-replication:
ipv4_address: 172.25.0.101
slave1:
image: 10.30.30.22:9080/library/redis:5.0.5
container_name: redis-slave-1
ports:
- "6380:6379"
volumes:
- "./slave1/redis.conf:/etc/redis.conf"
- "./slave1/data:/data"
command: redis-server --slaveof redis-master 6379
restart: always
networks:
redis-replication:
ipv4_address: 172.25.0.102
slave2:
image: 10.30.30.22:9080/library/redis:5.0.5
container_name: redis-slave-2
ports:
- "6381:6379"
volumes:
- "./slave2/redis.conf:/etc/redis.conf"
- "./slave2/data:/data"
command: redis-server --slaveof redis-master 6379
restart: always
networks:
redis-replication:
ipv4_address: 172.25.0.103
执行
docker-compose -f docker-compose-master-slave.yaml up -d
执行即可搭建好
验证:一个输入,在另外节点查询
搭建哨兵
第一步先搭建主从,上面的配置即可
第二步,搭建哨兵
放置的目录
.
├── docker-compose-master-slave.yaml
├── docker-compose-sentinel.yaml
├── sentinel1.conf
├── sentinel2.conf
└── sentinel3.conf
version: '3'
services:
sentinel1:
image: 10.30.30.22:9080/library/redis:5.0.5
container_name: redis-sentinel-1
ports:
- 26379:26379
command: redis-sentinel /usr/local/etc/redis/sentinel.conf
restart: always
volumes:
- ./sentinel1.conf:/usr/local/etc/redis/sentinel.conf
sentinel2:
image: 10.30.30.22:9080/library/redis:5.0.5
container_name: redis-sentinel-2
ports:
- 26380:26379
command: redis-sentinel /usr/local/etc/redis/sentinel.conf
volumes:
- ./sentinel2.conf:/usr/local/etc/redis/sentinel.conf
sentinel3:
image: 10.30.30.22:9080/library/redis:5.0.5
container_name: redis-sentinel-3
ports:
- 26381:26379
command: redis-sentinel /usr/local/etc/redis/sentinel.conf
volumes:
- ./sentinel3.conf:/usr/local/etc/redis/sentinel.conf
networks:
default:
external:
name: sentinel_redis-replication
sentinel.conf三个配置都一样
# 哨兵sentinel实例运行的端口 默认26379
port 26379
# myid
# 哨兵sentinel的工作目录
dir /tmp
# 自定义集群名,其中 172.25.0.101 为 redis-master 的 ip,6379 为 redis-master 的端口,2 为最小投票数(因为有 3 台 Sentinel 所以可以设置成 2)
sentinel monitor mymaster 172.25.0.101 6379 2
sentinel down-after-milliseconds mymaster 30000
sentinel parallel-syncs mymaster 1
sentinel auth-pass mymaster 123456
sentinel failover-timeout mymaster 180000
sentinel deny-scripts-reconfig yes
搭建集群
.
├── cluster-6381.conf
├── cluster-6382.conf
├── cluster-6383.conf
├── cluster-6384.conf
├── cluster-6385.conf
├── cluster-6386.conf
└── docker-compose-cluster.yaml
version: '3'
services:
redis-6381:
container_name: redis-cluster-1
image: 10.30.30.22:9080/library/redis:5.0.5
command: redis-server /etc/usr/local/redis.conf
ports:
- "6381:6381"
volumes:
- ./cluster-6381.conf:/etc/usr/local/redis.conf
- ./redis-6381/data:/data
redis-6382:
container_name: redis-cluster-2
image: 10.30.30.22:9080/library/redis:5.0.5
command: redis-server /etc/usr/local/redis.conf
ports:
- "6382:6382"
volumes:
- ./cluster-6382.conf:/etc/usr/local/redis.conf
- ./redis-6382/data:/data
redis-6383:
container_name: redis-cluster-3
image: 10.30.30.22:9080/library/redis:5.0.5
command: redis-server /etc/usr/local/redis.conf
ports:
- "6383:6383"
volumes:
- ./cluster-6383.conf:/etc/usr/local/redis.conf
- ./redis-6383/data:/data
redis-6384:
container_name: redis-cluster-4
image: 10.30.30.22:9080/library/redis:5.0.5
command: redis-server /etc/usr/local/redis.conf
ports:
- "6384:6384"
volumes:
- ./cluster-6384.conf:/etc/usr/local/redis.conf
- ./redis-6384/data:/data
redis-6385:
container_name: redis-cluster-5
image: 10.30.30.22:9080/library/redis:5.0.5
command: redis-server /etc/usr/local/redis.conf
ports:
- "6385:6385"
volumes:
- ./cluster-6385.conf:/etc/usr/local/redis.conf
- ./redis-6385/data:/data
redis-6386:
container_name: redis-cluster-6
image: 10.30.30.22:9080/library/redis:5.0.5
command: redis-server /etc/usr/local/redis.conf
ports:
- "6386:6386"
volumes:
- ./cluster-6386.conf:/etc/usr/local/redis.conf
- ./redis-6386/data:/data
protected-mode no
#bind 127.0.0.1
port 6381
# 开启集群模式
cluster-enabled yes
protected-mode no
#bind 127.0.0.1
port 6382
# 开启集群模式
cluster-enabled yes
protected-mode no
#bind 127.0.0.1
port 6383
# 开启集群模式
cluster-enabled yes
protected-mode no
#bind 127.0.0.1
port 6384
# 开启集群模式
cluster-enabled yes
protected-mode no
#bind 127.0.0.1
port 6385
# 开启集群模式
cluster-enabled yes
protected-mode no
#bind 127.0.0.1
port 6386
# 开启集群模式
cluster-enabled yes
启动容器
docker-compose -f docker-compose-cluster.yaml up -d
配置槽位
docker exec -it redis-cluster-1 redis-cli -p 6381 --cluster fix localhost:6381
docker exec -it redis-cluster-2 redis-cli -p 6382 --cluster fix localhost:6382
docker exec -it redis-cluster-3 redis-cli -p 6383 --cluster fix localhost:6383
docker exec -it redis-cluster-4 redis-cli -p 6384 --cluster fix localhost:6384
docker exec -it redis-cluster-5 redis-cli -p 6385 --cluster fix localhost:6385
docker exec -it redis-cluster-6 redis-cli -p 6386 --cluster fix localhost:6386
配置集群
查找每个节点的ip并进行配置
查找对应ip命令
docker exec -it redis-cluster-1 cat /etc/hosts
配置集群关联
docker exec -it redis-cluster-1 redis-cli -p 6381 --cluster create 172.27.0.4:6381 172.27.0.2:6382 172.27.0.6:6383 172.27.0.5:6384 172.27.0.3:6385 172.27.0.7:6386 --cluster-replicas 1
遇到需要输入,输入yes即可
java使用
.
├── Dockerfile
├── pom.xml
└── src
└── main
├── java
│ └── com
│ └── github
│ └── test
│ ├── DemoApplication.java
│ ├── config
│ │ └── RedisConfig.java
│ └── controller
│ └── DemoController.java
└── resources
└── application.yml
package com.isyscore.os.config;
import com.fasterxml.jackson.annotation.JsonAutoDetect;
import com.fasterxml.jackson.annotation.PropertyAccessor;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer;
import org.springframework.data.redis.serializer.StringRedisSerializer;
@Configuration
public class RedisConfig {
@Bean(name = "redisTemplate")
public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory redisConnectionFactory) {
Jackson2JsonRedisSerializer<Object> jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer<>(Object.class);
ObjectMapper om = new ObjectMapper();
om.disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES);
om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
om.activateDefaultTyping(om.getPolymorphicTypeValidator(), ObjectMapper.DefaultTyping.NON_FINAL);
jackson2JsonRedisSerializer.setObjectMapper(om);
RedisTemplate<String, Object> template = new RedisTemplate<>();
template.setConnectionFactory(redisConnectionFactory);
template.setKeySerializer(new StringRedisSerializer());
template.setValueSerializer(jackson2JsonRedisSerializer);
template.setHashKeySerializer(jackson2JsonRedisSerializer);
template.setHashValueSerializer(jackson2JsonRedisSerializer);
template.afterPropertiesSet();
return template;
}
//字符串建议使用StringRedisTemplate
@Bean("stringRedisTemplate")
public StringRedisTemplate stringRedisTemplate(RedisConnectionFactory redisConnectionFactory) {
StringRedisTemplate template = new StringRedisTemplate();
template.setConnectionFactory(redisConnectionFactory);
return template;
}
}
/**
* @author shizi
* @since 2022-05-24 10:19:26
*/
@RequestMapping("api/demo")
@RestController
public class DemoController {
@Autowired
private StringRedisTemplate stringRedisTemplate;
@GetMapping("set/{key}/{value}")
private String setValue(@PathVariable("key") String key, @PathVariable("value") String value) {
stringRedisTemplate.opsForValue().set(key, value, 1, TimeUnit.HOURS);
return "ok";
}
@GetMapping("get/{key}")
private String getValue(@PathVariable("key") String key) {
return stringRedisTemplate.opsForValue().get(key);
}
}
spring:
redis:
host: 172.17.0.2
port: 6379
# sentinel:
# master: mymaster
# nodes:
# - 172.25.0.2:26379
# - 172.25.0.3:26379
# - 172.25.0.4:26379
cluster:
nodes:
- 172.27.0.4:6381
- 172.27.0.2:6382
- 172.27.0.6:6383
- 172.27.0.5:6384
- 172.27.0.3:6385
- 172.27.0.7:6386
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.2.6.RELEASE</version>
</parent>
<groupId>com.isyscore.os</groupId>
<artifactId>isc-redis-test</artifactId>
<version>1.0.0</version>
<dependencies>
<!-- redis start -->
<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-redis</artifactId>
</dependency>
<dependency>
<groupId>io.lettuce</groupId>
<artifactId>lettuce-core</artifactId>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-core</artifactId>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.datatype</groupId>
<artifactId>jackson-datatype-jsr310</artifactId>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
</dependency>
<!-- redis end -->
<!-- spring -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-actuator-autoconfigure</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-actuator</artifactId>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
FROM docker.io/itoak/java8:1.0.0
# 容器启动后的工作目录
WORKDIR /opt
# 将jar包添加到容器内
ADD xxx.jar server.jar
# 容器启动后 执行命令
CMD java -jar server.jar
打容器镜像(标签自行打,我这里是哨兵使用sentinel,集群使用cluster)
docker build -t redis-java-test:sentinel .
docker build -t redis-java-test:cluster .
运行时候有不同,要将对应的测试镜像所在网络与哨兵或者集群应该在同一个网络
docker network ls
上面的哨兵和集群配置最后生成的网络分别如下,在运行测试用例的时候要带上对应的网络
- cluster_default:这个是集群的网络
- sentinel_redis-replication:这个是哨兵的网络
哨兵下的运行命令
docker run --network sentinel_redis-replication --name redis-java-sentinel -d -p 28080:8080 redis-java-test:sentinel
集群下的运行命令
docker run --network cluster_default --name redis-java-cluster -d -p 28081:8080 redis-java-test:cluster
go使用
go代码这里使用了go-redis,不过进行了一些封装,使用方式请见https://github.com/isyscore/isc-gobase/tree/main/redis
go get github.com/isyscore/isc-gobase�
.
├── Dockerfile
├── application.yml
├── go.mod
└── main.go
#build stage
FROM golang:1.18 as builder
RUN go version
ENV GO111MODULE=on
ENV GOPROXY=https://goproxy.cn
WORKDIR /app
COPY . /app/
RUN CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -o /app
EXPOSE 8081
#image stage
FROM alpine:latest
WORKDIR /app
ENV TZ=Asia/Shanghai
ENV ZONEINFO=/app/zoneinfo.zip
COPY --from=builder /app/application.yml /app/application.yml
#COPY --from=builder /app/config/application-default.yml /app/config/application-default.yml
COPY --from=builder /app/base-redis-test /app/base-redis-test
COPY --from=builder /usr/local/go/lib/time/zoneinfo.zip /app
CMD ["./base-redis-test"]
base:
application:
name: sample
server:
enable: true
port: 32005
gin:
# 有三种模式:debug/release/test
mode: debug
redis:
enable: true
# standalone:
# addr: redis-standalone:6379
# sentinel:
# master: mymaster
# addrs:
# - redis-sentinel-1:26379
# - redis-sentinel-2:26379
# - redis-sentinel-3:26379
cluster:
addrs:
- localhost:6381
- localhost:6382
- localhost:6383
- localhost:6384
- localhost:6385
- localhost:6386
max-redirects: 4
构建
go build
然后执行打镜像,镜像手法与java同样