Redis 简介
Redis 是一个基于 C 语言开发的开源(BSD 许可), 开源高性能的高级内存数据结构存储, 用作数据库, 缓存和消息代理. 它支持数据结构, 如 字符串, 散列, 列表, 集合, 带有范围查询的排序集, 位图, 超级日志, 具有半径查询和流的地理空间索引. Redis 具有内置复制, Lua 脚本, LRU 驱逐, 事务和不同级别的磁盘持久性, 并通过 Redis Sentinel 和 Redis Cluster 自动分区.
可以对这些数据类型进行原子性操作, 例如 附加到字符串; 递增哈希值; 将元素推送到列表中; 计算集合交集, 并集和差异; 或则在排序中获得排名最高的成员. 为了实现其出色的性能, Redis 使用内存数据集. 根据您的配置情况, 可以通过 每隔一段时间将数据集转存储到磁盘或通过每个命令附加到日志文件来保存它. 如果您只需要功能丰富的网络内存缓存, 则可以选择禁用持久性.
Redis 还支持简单到设置的主从异步复制, 具有非常快速的非阻塞第一次同步, 自动重新连接以及在网络分割上的部分重新同步.
核心对象
- 192.168.56.101 7000,1001,7002;
- 192.168.56.102 7003,7004,7005
- wget http://download.redis.io/releases/redis-4.0.10.tar.gz
- tar xzf Redis-4.0.10.tar.gz
- cd Redis-4.0.10
- make
- vi 7000/Redis.conf
- vi 7001/Redis.conf
- vi 7002/Redis.conf
- port 7000
- bind 192.168.56.101
- daemonize yes
- pidfile /var/run/redis_7000.pid
- logfile /var/log/Redis/redis_7000.log
- cluster-enabled yes
- cluster-config-file nodes_7000.conf
- cluster-node-timeout 10100
- dbfilename dump_7000.rdb
- appendonly yes
- appendfilename "appendonly_7000.aof"
- # 端口 7000,7001,7002
- port 7000
- # 默认 ip 为 127.0.0.1, 需要改为其他节点机器可访问的 ip, 否则创建集群时无法访问对应的端口, 无法创建集群
- bind 192.168.56.101
- #Redis 后台运行
- daemonize yes
- #pidfile 文件对应 7000,7001,7002
- pidfile /var/run/redis_7000.pid
- # 开启集群, 把注释 #去掉
- cluster-enabled yes
- # 集群的配置, 配置文件首次启动自动生成 7000,7001,7002
- cluster-config-file nodes_7000.conf
- # 请求超时, 默认 15 秒, 可自行设置
- cluster-node-timeout 10100
- #aof 日志开启, 有需要就开启, 它会每次写操作都记录一条日志
- appendonly yes
- # 第一台机器上执行 3 个节点
- for((i=0;i<=2;i++)); do /opt/Redis-4.0.10/src/Redis-server /opt/Redis-4.0.10/Redis-cluster/700$i/Redis.conf; done
- # 第二台机器上执行 3 个节点
- for((i=3;i<=5;i++)); do /opt/Redis-4.0.10/src/Redis-server /opt/Redis-4.0.10/Redis-cluster/700$i/Redis.conf; done
- # 启动单个节点示例
- /opt/Redis-4.0.10/src/Redis-server /opt/Redis-4.0.10/Redis-cluster/7000/Redis.conf
- ps -ef | grep Redis //Redis 是否启动成功
- netstat -tnlp | grep Redis // 监听 Redis 端口
- yum -y install Ruby Ruby-devel RubyGems rpm-build
- Gem install Redis
- [root@master1 /]# /opt/Redis-4.0.10/src/Redis-trib.rb create --replicas 1 192.168.56.101:7000 192.168.56.101:7001 192.168.56.101:7002 192.168.56.102:7003 192.168.56.102:7004 192.168.56.102:7005
- >>> Creating cluster
- >>> Performing hash slots allocation on 6 nodes...
- Using 3 masters:
- 192.168.56.101:7000
- 192.168.56.102:7003
- 192.168.56.101:7001
- Adding replica 192.168.56.102:7005 to 192.168.56.101:7000
- Adding replica 192.168.56.101:7002 to 192.168.56.102:7003
- Adding replica 192.168.56.102:7004 to 192.168.56.101:7001
- M: 6af67c2741b3001e6d328621ac8a2e539b65d683 192.168.56.101:7000
- slots:0-5460 (5461 slots) master
- M: e2f298953141f46b255b0f35372af917afc16205 192.168.56.101:7001
- slots:10923-16383 (5461 slots) master
- S: 3516ed59324a7421878b2c17aba44d91ec7e9439 192.168.56.101:7002
- replicates ab5b4535f3382c13d7afb91d005e8a87d830eb46
- M: ab5b4535f3382c13d7afb91d005e8a87d830eb46 192.168.56.102:7003
- slots:5461-10922 (5462 slots) master
- S: 16822c6d58461f9edaf965aa53efdac59d1adce5 192.168.56.102:7004
- replicates e2f298953141f46b255b0f35372af917afc16205
- S: c00dea4a44e01e1f17b29f7b3b95e0c57b06a653 192.168.56.102:7005
- replicates 6af67c2741b3001e6d328621ac8a2e539b65d683
- Can I set the above configuration? (type 'yes' to accept): yes
- >>> Nodes configuration updated
- >>> Assign a different config epoch to each node
- >>> Sending CLUSTER MEET messages to join the cluster
- Waiting for the cluster to join....
- >>> Performing Cluster Check (using node 192.168.56.101:7000)
- M: 6af67c2741b3001e6d328621ac8a2e539b65d683 192.168.56.101:7000
- slots:0-5460 (5461 slots) master
- 1 additional replica(s)
- S: c00dea4a44e01e1f17b29f7b3b95e0c57b06a653 192.168.56.102:7005
- slots: (0 slots) slave
- replicates 6af67c2741b3001e6d328621ac8a2e539b65d683
- S: 3516ed59324a7421878b2c17aba44d91ec7e9439 192.168.56.101:7002
- slots: (0 slots) slave
- replicates ab5b4535f3382c13d7afb91d005e8a87d830eb46
- M: ab5b4535f3382c13d7afb91d005e8a87d830eb46 192.168.56.102:7003
- slots:5461-10922 (5462 slots) master
- 1 additional replica(s)
- S: 16822c6d58461f9edaf965aa53efdac59d1adce5 192.168.56.102:7004
- slots: (0 slots) slave
- replicates e2f298953141f46b255b0f35372af917afc16205
- M: e2f298953141f46b255b0f35372af917afc16205 192.168.56.101:7001
- slots:10923-16383 (5461 slots) master
- 1 additional replica(s)
- [OK] All nodes agree about slots configuration.
- >>> Check for open slots...
- >>> Check slots coverage...
- [OK] All 16384 slots covered.
- for((i=0;i<=2;i++)); do /opt/Redis-4.0.10/src/Redis-cli -c -h 192.168.56.101 -p 700$i shutdown; done
- for((i=3;i<=5;i++)); do /opt/Redis-4.0.10/src/Redis-cli -c -h 192.168.56.102 -p 700$i shutdown; done
- set name xushuyi
- get name
- <!-- redis -->
- <dependency>
- <groupId>org.springframework.boot</groupId>
- <artifactId>spring-boot-starter-data-Redis</artifactId>
- </dependency>
- <!-- redis 依赖 commons-pool -->
- <dependency>
- <groupId>org.apache.commons</groupId>
- <artifactId>commons-pool2</artifactId>
- </dependency>
- # Redis 集群配置
- spring:
- Redis:
- cluster:
- nodes: 192.168.56.101:7000,192.168.56.101:7001,192.168.56.101:7002,192.168.56.102:7003,192.168.56.102:7004,192.168.56.102:7005
- timeout: 6000ms # 连接池超时时间(毫秒)
- # 密码没有可以不填
- password:
- database: 0 # 数据库索引
- lettuce:
- pool:
- max-active: 8 # 连接池最大活跃连接数(使用负值表示没有限制)
- max-idle: 8 # 连接池最大空闲连接数
- max-wait: -1ms # 连接池最大阻塞等待时间 毫秒(使用负值表示没有限制)
- min-idle: 0 # 最小空闲连接数
- package com.sinosoft.config;
- import com.fasterxml.jackson.annotation.JsonAutoDetect;
- import com.fasterxml.jackson.annotation.PropertyAccessor;
- import com.fasterxml.jackson.databind.ObjectMapper;
- import org.springframework.boot.autoconfigure.AutoConfigureAfter;
- import org.springframework.boot.autoconfigure.data.Redis.RedisAutoConfiguration;
- import org.springframework.context.annotation.Bean;
- import org.springframework.context.annotation.Configuration;
- import org.springframework.data.Redis.connection.lettuce.LettuceConnectionFactory;
- import org.springframework.data.Redis.core.RedisTemplate;
- import org.springframework.data.Redis.serializer.Jackson2JsonRedisSerializer;
- import org.springframework.data.Redis.serializer.StringRedisSerializer;
- /**
- * @ClassName: RedisConfig
- * @Description: Redis 配置
- * @author: Created by xushuyi <a href="xu_xxx1002@163.com">Contact author</a>
- * @date: 2019/2/28 16:01
- * @Version: V1.0
- */
- @Configuration
- @AutoConfigureAfter(RedisAutoConfiguration.class)
- public class RedisConfig {
- /**
- * 注入自定义的 RedisTemplate
- *
- * @param redisConnectFactory LettuceConnectionFactory
- * @return RedisTemplate
- */
- @Bean
- public RedisTemplate<String, Object> redisTemplate(LettuceConnectionFactory redisConnectFactory) {
- RedisTemplate<String, Object> redisTemplate = new RedisTemplate<>();
- redisTemplate.setConnectionFactory(redisConnectFactory);
- // 使用 Jackson2JsonRedisSerializer 来序列化和反序列化 Redis 的 value 值
- Jackson2JsonRedisSerializer jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer(Object.class);
- ObjectMapper objectMapper = new ObjectMapper();
- objectMapper.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
- objectMapper.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
- jackson2JsonRedisSerializer.setObjectMapper(objectMapper);
- redisTemplate.setValueSerializer(jackson2JsonRedisSerializer);
- // 使用 StringRedisSerializer 来序列化和反序列化 Redis 的 key 值
- redisTemplate.setKeySerializer(new StringRedisSerializer());
- redisTemplate.setHashKeySerializer(new StringRedisSerializer());
- redisTemplate.setHashValueSerializer(new StringRedisSerializer());
- redisTemplate.afterPropertiesSet();
- return redisTemplate;
- }
- }
- package com.sinosoft.Redis;
- import com.sinosoft.AccountApplication;
- import lombok.extern.slf4j.Slf4j;
- import org.junit.After;
- import org.junit.Before;
- import org.junit.Test;
- import org.junit.runner.RunWith;
- import org.springframework.beans.factory.annotation.Autowired;
- import org.springframework.boot.test.context.SpringBootTest;
- import org.springframework.cache.annotation.Cacheable;
- import org.springframework.context.annotation.Import;
- import org.springframework.data.Redis.core.RedisTemplate;
- import org.springframework.test.context.ActiveProfiles;
- import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
- import org.springframework.test.context.web.WebAppConfiguration;
- /**
- * @ClassName: RedisTest
- * @Description: Redis 测试
- * @author: Created by xushuyi <a href="xu_shuyi1002@163.com">Contact author</a>
- * @date: 2019/2/28 16:18
- * @Version: V1.0
- */
- @Slf4j
- @RunWith(SpringJUnit4ClassRunner.class) // SpringJUnit 支持, 由此引入 Spring-Test 框架支持!
- @SpringBootTest
- @Import(AccountApplication.class) // 指定我们 SpringBoot 工程的 Application 启动类
- @ActiveProfiles(profiles = "dev") // 指定 Application 启动需要引用的配置文件
- @WebAppConfiguration // 由于是 Web 项目, Junit 需要模拟 ServletContext, 因此我们需要给我们的测试类加上 @WebAppConfiguration
- public class RedisTest {
- /**
- * 获取 RedisTemplate
- */
- @Autowired
- private RedisTemplate redisTemplate;
- /**
- * 测试前
- */
- @Before
- public void before() {
- log.info("测试前...");
- }
- /**
- * 开始测试
- */
- @Test
- public void redisTest() {
- // 测试通过 RedisTemplate 操作
- redisTemplate.opsForValue().set("name", "huachunjie");
- Object name = redisTemplate.opsForValue().get("name");
- log.info("获取 Redis 集群中 key 为 name 对应的值:{}", name);
- }
- @After
- public void after() {
- log.info("测试后...");
- }
- }
- /**
- * 测试 Redis 缓存
- *
- * @param requestInfo 入参
- * @return
- */
- @Override
- @Cacheable(value = "cacheInfo", key = "#requestInfo.token", condition = "#requestInfo != null")
- public ResponseInfo testRedis(RequestInfo<String> requestInfo) {
- log.info("如果没有进来, 则说明启用了 Redis 缓存...");
- return new ResponseInfo<>(true, "success", 200, null);
- }
来源: https://www.cnblogs.com/xushuyi/p/10455308.html