Redis介绍
Redis是一个开源,先进的key-value存储,并用于构建高性能,可扩展的Web应用程序的完美解决方案。
Redis从它的许多竞争继承来的三个主要特点:
-
Redis数据库完全在内存中,使用磁盘仅用于持久性。
-
相比许多键值数据存储,Redis拥有一套较为丰富的数据类型。
-
Redis可以将数据复制到任意数量的从服务器。
Redis 优势
-
异常快速:Redis的速度非常快,每秒能执行约11万集合,每秒约81000+条记录。
-
支持丰富的数据类型:Redis支持最大多数开发人员已经知道像列表,集合,有序集合,散列数据类型。这使得它非常容易解决各种各样的问题,因为我们知道哪些问题是可以处理通过它的数据类型更好。
-
操作都是原子性:所有Redis操作是原子的,这保证了如果两个客户端同时访问的Redis服务器将获得更新后的值。
-
多功能实用工具:Redis是一个多实用的工具,可以在多个用例如缓存,消息,队列使用(Redis原生支持发布/订阅),任何短暂的数据,应用程序,如Web应用程序会话,网页命中计数等。
下载windows版本的Redis
去官网找了很久,发现原来在官网上可以下载的windows版本的,现在官网以及没有下载地址,只能在github上下载,官网只提供linux版本的下载
官网下载地址:http://redis.io/download
github下载地址:https://github.com/MSOpenTech/redis/tags
https://github.com/MicrosoftArchive/redis/releases
. 这里下载的是Redis-x64-3.2.100版本,我的电脑是win7 64位,所以下载64位版本的,在运行中输入cmd,然后把目录指向解压的Redis目录。
双击redis-server.exe 启动redis。
Redistemplate 配置
<bean id="sessionJedisPoolConfig" class="redis.clients.jedis.JedisPoolConfig">
<property name="maxTotal" value="${sessionRedis.pool.maxTotal}" />
<property name="maxWaitMillis" value="${sessionRedis.pool.maxWaitMillis}" />
<property name="maxIdle" value="${sessionRedis.pool.maxIdle}" />
<property name="testOnBorrow" value="${sessionRedis.pool.testOnBorrow}" />
</bean>
<bean id="sessionJedisConnectionFactory"
class="org.springframework.data.redis.connection.jedis.JedisConnectionFactory">
<property name="hostName" value="${sessionRedis.ip}" />
<property name="port" value="${sessionRedis.port}" />
<property name="database" value="${sessionRedis.db}"></property>
<property name="poolConfig" ref="sessionJedisPoolConfig" />
</bean>
<bean id="sessionRedisTemplate" class="org.springframework.data.redis.core.RedisTemplate">
<property name="connectionFactory">
<ref bean="sessionJedisConnectionFactory" />
</property>
</bean>
Redis 队列使用
加入队列
jedis.rpush("test", "1");
jedis.rpush("test", "2");
取队列
for(int i = 0 ; i<3 ; i++){
System.out.println("jedis-rpop"+jedis.lpop("test"));
}
Redis 订阅使用
以springboot - redisTemplate 为例子
application-dev.properties 配置:
1 # RedisProperties 2 # Redis数据库索引(默认为0) 3 spring.redis.database=0 4 # Redis服务器地址 5 spring.redis.host=127.0.0.1 6 # Redis服务器连接端口 7 spring.redis.port=6379 8 # Redis服务器连接密码(默认为空) 9 spring.redis.password= 10 # 连接池最大连接数(使用负值表示没有限制) 11 spring.redis.pool.max-active=8 12 # 连接池最大阻塞等待时间(使用负值表示没有限制) 13 spring.redis.pool.max-wait=-1 14 # 连接池中的最大空闲连接 15 spring.redis.pool.max-idle=8 16 # 连接池中的最小空闲连接 17 spring.redis.pool.min-idle=0 18 # 连接超时时间(毫秒) 19 spring.redis.timeout=0
1 package com.aisino.projects.config; 2 3 import org.slf4j.Logger; 4 import org.slf4j.LoggerFactory; 5 import org.springframework.beans.factory.annotation.Value; 6 import org.springframework.boot.autoconfigure.EnableAutoConfiguration; 7 import org.springframework.boot.context.properties.ConfigurationProperties; 8 import org.springframework.context.annotation.Bean; 9 import org.springframework.context.annotation.Configuration; 10 import org.springframework.data.redis.connection.jedis.JedisConnectionFactory; 11 import org.springframework.data.redis.core.RedisTemplate; 12 import org.springframework.data.redis.core.StringRedisTemplate; 13 14 import redis.clients.jedis.JedisPoolConfig; 15 16 17 /** 18 * Redis配置 19 * @author aisino-xxy 20 * @date 2018年2月12日 下午5:45:44 21 */ 22 @Configuration 23 @EnableAutoConfiguration 24 public class RedisConfig { 25 26 private Logger logger = LoggerFactory.getLogger(getClass()); 27 28 //获取springboot配置文件的值 (get的时候获取) 29 @Value("${spring.redis.host}") 30 private String host; 31 32 @Value("${spring.redis.password}") 33 private String password; 34 35 36 /** 37 * @Bean 和 @ConfigurationProperties 38 * 该功能在官方文档是没有提到的,我们可以把@ConfigurationProperties和@Bean和在一起使用。 39 * 举个例子,我们需要用@Bean配置一个Config对象,Config对象有a,b,c成员变量需要配置, 40 * 那么我们只要在yml或properties中定义了a=1,b=2,c=3, 41 * 然后通过@ConfigurationProperties就能把值注入进Config对象中 42 * @return 43 */ 44 @Bean 45 @ConfigurationProperties(prefix = "spring.redis.pool") 46 public JedisPoolConfig getRedisConfig() { 47 JedisPoolConfig config = new JedisPoolConfig(); 48 return config; 49 } 50 51 @Bean 52 @ConfigurationProperties(prefix = "spring.redis") 53 public JedisConnectionFactory getConnectionFactory() { 54 JedisConnectionFactory factory = new JedisConnectionFactory(); 55 factory.setUsePool(true); 56 JedisPoolConfig config = getRedisConfig(); 57 factory.setPoolConfig(config); 58 logger.info("JedisConnectionFactory bean init success."); 59 return factory; 60 } 61 62 63 @Bean 64 public RedisTemplate<?, ?> getRedisTemplate() { 65 JedisConnectionFactory factory = getConnectionFactory(); 66 logger.info(this.host+","+factory.getHostName()+","+factory.getDatabase()); 67 logger.info(this.password+","+factory.getPassword()); 68 RedisTemplate<?, ?> template = new StringRedisTemplate(getConnectionFactory()); 69 return template; 70 } 71 }
服务端:
1 package com.aisino.projects.task.web.redistemplate.service.impl; 2 3 import org.springframework.beans.factory.annotation.Autowired; 4 import org.springframework.data.redis.core.RedisTemplate; 5 import org.springframework.stereotype.Service; 6 7 import com.aisino.projects.task.web.redistemplate.service.RedisService; 8 9 10 /** 11 * RedisService实现 12 * @author aisino-xxy 13 * @date 2018年2月12日 下午5:03:38 14 */ 15 @Service 16 public class RedisServiceImpl implements RedisService { 17 18 @Autowired 19 private RedisTemplate<String,Object> redisTemplate; 20 21 @Override 22 public void publishMsg() { 23 redisTemplate.convertAndSend("redisTopic", "使用redisTopic向通道发送消息"); 24 redisTemplate.convertAndSend("redisTopic22", "使用redisTopic22向通道发送消息"); 25 } 26 27 }
客户端:
1 package com.aisino.projects.config; 2 3 import org.springframework.context.annotation.Bean; 4 import org.springframework.context.annotation.Configuration; 5 import org.springframework.data.redis.connection.RedisConnectionFactory; 6 import org.springframework.data.redis.core.StringRedisTemplate; 7 import org.springframework.data.redis.listener.PatternTopic; 8 import org.springframework.data.redis.listener.RedisMessageListenerContainer; 9 import org.springframework.data.redis.listener.adapter.MessageListenerAdapter; 10 11 import com.aisino.projects.task.web.redistemplate.service.RedisReceiver; 12 13 @Configuration 14 public class RedisSubListenerConfig { 15 16 //初始化监听器 17 @Bean 18 RedisMessageListenerContainer container(RedisConnectionFactory connectionFactory, 19 MessageListenerAdapter listenerAdapter) { 20 RedisMessageListenerContainer container = new RedisMessageListenerContainer(); 21 container.setConnectionFactory(connectionFactory); 22 container.addMessageListener(listenerAdapter, new PatternTopic("redisTopic")); 23 container.addMessageListener(listenerAdapter, new PatternTopic("redisTopic22")); 24 return container; 25 } 26 27 28 //利用反射来创建监听到消息之后的执行方法 29 @Bean 30 MessageListenerAdapter listenerAdapter(RedisReceiver redisReceiver) { 31 return new MessageListenerAdapter(redisReceiver, "receiveMessage"); 32 } 33 34 //使用默认的工厂初始化redis操作模板 35 @Bean 36 StringRedisTemplate template(RedisConnectionFactory connectionFactory) { 37 return new StringRedisTemplate(connectionFactory); 38 } 39 }
package com.aisino.projects.task.web.redistemplate.service; import org.springframework.stereotype.Service; @Service public class RedisReceiver { public void receiveMessage(String message) { //这里是收到通道的消息之后执行的方法 //System.out.println("频道: " + message.getChannel() + ";内容 :" + message.getBody()); System.out.println("RedisReceiver监听消息: " + message); } }
Redis 其他使用
//是否存在
jedis.exists("computer1");
redis 计数器
jedis.incr("computer"); jedis.decr("computer");
Redis 分布式锁
SETNX key val
当且仅当key不存在时,set一个key为val的字符串,返回1;若key存在,则什么都不做,返回0。
expire key timeout
为key设置一个超时时间,单位为second,超过这个时间锁会自动释放,避免死锁。
// 获取连接
Jedis conn = jedisPool.getResource();
// 锁名,即key值
String lockKey = "lock:order" ;
// 超时时间60秒,上锁后超过此时间则自动释放锁
int lockExpire = 60;
if (conn.setnx(lockKey, identifier) == 1) {
conn.expire(lockKey, lockExpire);
// 返回value值,用于释放锁时间确认
retIdentifier = identifier;
return retIdentifier;
}
// 返回-1代表key没有设置超时时间,为key设置一个超时时间
if (conn.ttl(lockKey) == -1) {
conn.expire(lockKey, lockExpire);
}