简介
- 性能极高 – Redis能读的速度是110000次/s,写的速度是81000次/s 。
- 丰富的数据类型 – Redis支持二进制案例的 Strings, Lists, Hashes, Sets 及 Ordered Sets 数据类型操作。
- 原子 – Redis的所有操作都是原子性的,意思就是要么成功执行要么失败完全不执行。单个操作是原子性的。多个操作也支持事务,即原子性,通过MULTI和EXEC指令包起来。
- 丰富的特性 – Redis还支持 publish/subscribe, 通知, key 过期等等特性。
spring+redis
- redis 单机版
// 第一步:创建一个JedisPool对象。需要指定服务端的ip及端口。
JedisPool jedisPool = new JedisPool("127.0.0.1", 6379);
// 第二步:从JedisPool中获得Jedis对象。
Jedis jedis = jedisPool.getResource();
现在就连接上 redis服务器了。所以在spring中我们要有jedisPool对象
- 添加依赖包
<dependency>
<groupId>redis.clients</groupId>
<artifactId>jedis</artifactId>
</dependency>
一般放在common 中,很多地方会用到缓存。
- 添加配置文件
<bean id="jedisPool" class="redis.clients.jedis.JedisPool">
<constructor-arg name="host" value="127.0.0.1"/>
<constructor-arg name="port" value="6379"/>
</bean>
通过jedispool 我们就可以获取连接了getResource();
然后就可以造成redis 存取数据了。
- 集群版
<bean id="jedisCluster" class="redis.clients.jedis.JedisCluster">
<constructor-arg name="nodes">
<set>
<bean class="redis.clients.jedis.HostAndPort">
<constructor-arg name="host" value="192.168.25.162"> </constructor-arg>
<constructor-arg name="port" value="7001"></constructor-arg>
</bean>
<bean class="redis.clients.jedis.HostAndPort">
<constructor-arg name="host" value="192.168.25.162"></constructor-arg>
<constructor-arg name="port" value="7002"></constructor-arg>
</bean>
</set>
</constructor-arg>
构造参数中传入set 集合,集合中存放的是HostAndPort,用来通知这些是集群。
获取jedisCluster 对象以后可以获取集群中的一个连接,进行数据存取。
在开发中一般使用单机开发,但是在实际运行中可能是集群版。为了不修改代码,只修改配置文件。可以写一个接口,开发中使用的是这个接口。这样代码就不用修改了。当然这个接口有两个实现类,一个是集群版一个是单机版。只需要修改spring bean 来让spring去创建对应的实例。接口的具体实现类会根据这个接口实现类进行赋值,只需要留一个实现类就可以了。
public interface JedisClient {
String set(String key, String value);
String get(String key);
Boolean exists(String key);
Long expire(String key, int seconds);
Long ttl(String key);
Long incr(String key);
Long hset(String key, String field, String value);
String hget(String key, String field);
Long hdel(String key, String... field);
}
接口中定义常用的方法
集群实习类
public class JedisClientCluster implements JedisClient {
private JedisCluster jedisCluster;
public JedisCluster getJedisCluster() {
return jedisCluster;
}
public void setJedisCluster(JedisCluster jedisCluster) {
this.jedisCluster = jedisCluster;
}
@Override
public String set(String key, String value) {
return jedisCluster.set(key, value);
}
@Override
public String get(String key) {
return jedisCluster.get(key);
}
。。。
}
单机版实现类
public class JedisClientPool implements JedisClient {
private JedisPool jedisPool;
public JedisPool getJedisPool() {
return jedisPool;
}
public void setJedisPool(JedisPool jedisPool) {
this.jedisPool = jedisPool;
}
@Override
public String set(String key, String value) {
Jedis jedis = jedisPool.getResource();
String result = jedis.set(key, value);
jedis.close();
return result;
}
@Override
public String get(String key) {
Jedis jedis = jedisPool.getResource();
String result = jedis.get(key);
jedis.close();
return result;
}
。。。
}
在spring中添加配置
单机版
<bean id="jedisClientPool" class="cn.v5.common.utils.JedisClientPool">
<property name="jedisPool" ref="jedisPool"></property>
</bean>
集群版
<bean id="jedisClientCluster" class="cn.v5.common.utils.JedisClientCluster">
<property name="jedisCluster" ref="jedisCluster"/>
</bean>
作用:
将Java对象存储到redis 中序列化。
将数据库的数据存储到redis 中
将对象中的数据以json 格式存储到redis 中。
Redis 中常用的数据类型存取
就是在内存中存储数据
注意 redis 中的数据都是 以字符串形式存储的
数据格式 hashmap 形式的
所以就是在 map 中存储数据
map.put(key,value)
map.put(key,hasmap(object))
- 命令
- set keyname value 设置键值对
- get keyname 根据keyname 找值
- keys * 所有的 key
- incr 变量加一
- 先对值 字符串 转换成整数(都是以字符串存储的)
- decr 变量加一
- del keyname 删除
- 存放hash 数据类型
- hset keyhashname keyname value
- hget keyhashname keyname
- hkeys keyhashname
- hvals keyhashname 取出所有值
- hgetall keyhashname 取出键值
- hdel
- 存放 list (有序)
- lpush keylistname value1 value2 ( value1先push ) 从左边添加
- rpush keylistname 从右边一个个push 进去
- lrange keylistname 0 -1 全部取出
- lpop 弹出取出
- set (无序 不可重复)
- sadd keysetname value1 value2
- sdiff setname1 setname2 setname1-setname 去掉重复的 留下a
- sinter setname1 setname2 取两个中都有的
- sunion setnmme1 setname2 取并集
- 设置有效期
- expire keyname second
- ttl keyname 查看生命时间 -1 是永久保存 -2 这个key不存在
- persist keyname 持久化
- 持久化就是 将 内存中存储到 rdb 文件中
Redis中的并发操作(简)
Lua语言操作是原子性的
eval 表示执行Lua语言
redis.call(‘set’,第一个参数,第二个参数)
set get del 等这就和 上面讲的一样了
例子:
eval "redis.call('hset',KEYS[1],KEYS[2],ARGV[1])" 2 test 1 man
这样就设置了
可以写写一些简单的逻辑
注意:
redis 一般在服务层,在进行对数据库操作的时候。同时对redis 进行跟新。
由于redis 实在缓存中操作所以存在数据丢失的风险,建议使用分布式,使用消息队列通知 ,redis 跟新。(每次在servic 层增删改 的时候通知redis 跟新。)