一、介紹 Redis誕生於2009年全稱是Remote Dictionary Server,遠程詞典伺服器,是一個基於記憶體 的鍵值型NoSQL資料庫。 特征: ●鍵值(key-value)型, value支持 多種不同數據結構,功能豐富 ●單線程, 每個命令具備原子性 ●低延遲,速度快(基於記憶體、1 ...
一、介绍
Redis诞生于2009年全称是Remote Dictionary Server,远程词典服务器,是一个基于内存 的键值型NoSQL数据库。
特征:
●键值(key-value)型, value支持 多种不同数据结构,功能丰富
●单线程, 每个命令具备原子性
●低延迟,速度快(基于内存、10多路复用、良好的编码)。
●支持数据持久化
●支持主从集群、分片集群
●支持多语言客户端
二、常用数据类型及用法
1. String类型
String分为3种格式:字符串、int、float
String的常见命令有:
●SET: 添加或者修改已经存在的一个String类型的键值对
●GET: 根据key获取String类型的value
●MSET: 批量添加多个String类型的键值对
●MGET: 根据多个key获取多个String类型的value
●INCR: 让一个整型的key自增1
●INCRBY: 让一个整型的key自增并指定步长,例如: incrby num 2让num值自增2
●INCRBYFLOAT: 让一个浮点类型的数字自增并指定步长
●SETNX: 添加一个String类型的键值对,前提是这个key不存在,否则不执行
●SETEX: 添加一个String类型的键值对,并且指定有效期
为了避免不同表的id值相同,为了区别开,key的层级格式可以定义为以下:
[项目名]:[业务名]:[类型]:[id]
2. Hash类型
Hash类型,也叫散列,其value是一个无序字典, 类似于Java中的HashMap结构。
Hash的常见命令有:
●HSET key field value: 添加或者修改hash类型key的field的值
●HGET key field: 获取一个hash类型key的field的值
●HMSET: 批量添加多个hash类型key的field的值
●HMGET: 批量获取多个hash类型key的field的值
●HGETALL: 获取一个hash类型的key中的所有的field和value
●HKEYS: 获取一个hash类型的key中的所有的field
●HVALS: 获取一个hash类型的key中的所有的value
●HINCRBY: 让一个hash类型key的字段值自增并指定步长
●HSETNX: 添加一个hash类型的key的field值,前提是这个field不存在,否则不执行
3. List类型
Redis中的List类型与Java中的LinkedList类似,可以看做是一个双向链表结构。既可以支持正向检索和也可以支持反向检索。
特征也与LinkedList类似:
●有序
●元素可以重复
●插入和删除快
●查询速度一般
List的常见命令有:
●LPUSH key element... :向列表左侧插入一个或多个元素
●LPOP key:移除并返回列表左侧的第一个元素,没有则返回nil
●RPUSH key element... :向列表右侧插入一个或多个元素
●RPOP key:移除并返回列表右侧的第一个元素
●LRANGE key star end:返回一 段角标范围内的所有元素
●BLPOP和BRPOP:与LPOP和RPOP类似,只不过在没有元素时等待指定时间,而不是直接返回nil
4. Set类型
Redis的Set结构与Java中的HashSet类似,可以看做是一个value为null的HashMap。因为也是一个hash表,因此具备与HashSet类似的特征:
●无序
●元素不可重复
●查找快
●支持交集、 并集、差集等功能
Set的常见命令有:
●SADD key member ... :向set中添加一一个或多个元素
●SREM key member ... :移除set中的指定元素
●SCARD key:返回set中元素的个数
●SISMEMBER key member:判断一个元素是否存在于set中
●SMEMBERS: 获取set中的所有元素
●SINTER key1 key2 ... :求key1 与key2的交集
●SDIFF key1 key2 ... :求key1与key2的差集
●SUNION key1 key2 ..:求key1和key2的并集
5. ZSet类型
Redis的ZSet是一个可排序的set集合,与Java中 的TreeSet有些类似,但底层数据结构却差别很大。ZSet中的每一个元素都带有一个score属性,可以基于score属性对元素排序,底层的实现是一个跳表(SkipList) 加hash表。
ZSet具备下列特性:
●可排序
●元素不重复
●查询速度快
因为ZSet的可排序特性,经常被用来实现排行榜这样的功能。
ZSet的常见命令有:
●ZADD key score member:添加一个或多个元素到Zset,如果已经存在则更新其score值
●ZREM key member:删除Zset中的一个指定元素
●ZSCORE key member :获取Zset中的指定元素的score值
●ZRANK key member:获取Zset中的指定元素的排名
●ZCARD key:获取Zset中的元素个数
●ZCOUNT key min max:统计score值在给定范围内的所有元素的个数
●ZINCRBY key increment member:让Zset中的指定元素自增,步长为指定的increment值
●ZRANGE key min max:按照score排序后,获取指定排名范围内的元素
●ZRANGEBYSCORE key min max:按照score排序后,获取指定score范围内的元素
●ZDIFF、 ZINTER、ZUNION:求差集、交集、并集
6. Bitmaps类型
Redis提供了Bitmaps这个“数据类型”可以实现对位的操作:
(1) Bitmaps本身不是一种数据类型, 实际上它就是字符串(key-value) , 但是它可以对字符串的位进行操作。
(2) Bitmaps单独提供了一套命令, 所以在Redis中使用Bitmaps和使用字符串的方法不太相同。 可以把Bitmaps想象成一个以位为单位的数组, 数组的每个单元只能存储0和1, 数组的下标在Bitmaps中叫做偏移量
当数据量特别大的时候,使用Bitmaps能够节省很多的內存空间,尤其是随着时间推移,节省的內存是非常可观的。
但是当数据量并不是非常大的时候,使用Bitmaps就不太合适了,因为基本大部分位都是0。
7. HyperLogLog类型
Redis HyperLogLog 是用来做基数统计的算法,HyperLogLog 的优点是,在输入元素的数量或者体积非常非常大时,计算基数所需的空间总是固定的、并且是很小的。
(1)pfadd:pfadd <key>< element> [element ...] 添加指定元素到 HyperLogLog 中
(2)pfcount: pfcount<key> [key ...] 计算HLL的近似基数,可以计算多个HLL,比如用HLL存储每天的UV
可查看基数的个数
(3)pfmerge:pfmerge<destkey><sourcekey> [sourcekey ...] 将一个或多个HLL合并后的结果存储在另一个HLL中。
示例将kll数据加入program中
8. Geospatial类型
Redis 3.2 中增加了对GEO类型的支持。GEO,Geographic,地理信息的缩写。该类型,就是元素的2维坐标,在地图上就是经纬度。redis基于该类型,提供了经纬度设置,查询,范围查询,距离查询,经纬度Hash等常见操作。
(1)geoadd:geoadd<key>< longitude><latitude><member> [longitude latitude member...] 添加地理位置(经度,纬度,名称)
也可以存储多个值
(2)geopos:geopos <key><member> [member...] 获得指定地区的坐标值
geopos <key><member> [member...] 获得指定地区的坐标值
(3)geodist:geodist<key><member1><member2> [m|km|ft|mi ] 根据设置的经纬度,获取两个位置之间的直线距离
(4)georadius:georadius<key>< longitude><latitude>radius m|km|ft|mi 以给定的经纬度为中心,找出某一半径内的元素
三、redis订阅和发布
Redis发布订阅(pub/sub) 是一种消息通信模式 :发送者(pub) 发送消息,订阅者(sub)接收消息。。
//客户端1进行订阅 subscribe channel1 //客户端2进行发布 publish channel1 hello
可见客户端1订阅后能够监视 channel1通道, 当客户端2向channel1通道发送数据时,客户端能够及时接收
四、Java中Redis操作
1.普通maven项目使用Jedis
(1)引入依赖
<dependency> <groupId>redis.clients</groupId> <artifactId>jedis</artifactId> <version>3.2.0</version> </dependency>
(2)测试代码
//创建Jedis对象 Jedis jedis = new Jedis("121.41.52.53",6379); //测试ping String ping = jedis.ping(); System.out.println(ping); //PONG
//获取所有keys值
Set<String> keys = jedis.keys("*");
for (String key : keys) {
System.out.println(key);
}
2. springboot集成redis
(1)引入依赖
<!-- redis --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-redis</artifactId> </dependency> <!-- spring2.X集成redis所需common-pool2--> <dependency> <groupId>org.apache.commons</groupId> <artifactId>commons-pool2</artifactId> <version>2.6.0</version> </dependency>
(2)properties文件配置
#Redis服务器地址
spring.redis.host=192.168.140.136
#Redis服务器连接端口
spring.redis.port=6379
#Redis数据库索引(默认为0)
spring.redis.database= 0
#连接超时时间(毫秒)
spring.redis.timeout=1800000
#连接池最大连接数(使用负值表示没有限制)
spring.redis.lettuce.pool.max-active=20
#最大阻塞等待时间(负数表示没限制)
spring.redis.lettuce.pool.max-wait=-1
#连接池中的最大空闲连接
spring.redis.lettuce.pool.max-idle=5
#连接池中的最小空闲连接
spring.redis.lettuce.pool.min-idle=0
(3)配置类
@EnableCaching @Configuration public class configuration extends CachingConfigurerSupport { @Bean public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory factory) { RedisTemplate<String, Object> template = new RedisTemplate<>(); RedisSerializer<String> redisSerializer = new StringRedisSerializer(); Jackson2JsonRedisSerializer jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer(Object.class); ObjectMapper om = new ObjectMapper(); om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY); om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL); jackson2JsonRedisSerializer.setObjectMapper(om); template.setConnectionFactory(factory); //key序列化方式 template.setKeySerializer(redisSerializer); //value序列化 template.setValueSerializer(jackson2JsonRedisSerializer); //value hashmap序列化 template.setHashValueSerializer(jackson2JsonRedisSerializer); return template; } @Bean public CacheManager cacheManager(RedisConnectionFactory factory) { RedisSerializer<String> redisSerializer = new StringRedisSerializer(); Jackson2JsonRedisSerializer jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer(Object.class); //解决查询缓存转换异常的问题 ObjectMapper om = new ObjectMapper(); om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY); om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL); jackson2JsonRedisSerializer.setObjectMapper(om); // 配置序列化(解决乱码的问题),过期时间600秒 RedisCacheConfiguration config = RedisCacheConfiguration.defaultCacheConfig() .entryTtl(Duration.ofSeconds(600)) .serializeKeysWith(RedisSerializationContext.SerializationPair.fromSerializer(redisSerializer)) .serializeValuesWith(RedisSerializationContext.SerializationPair.fromSerializer(jackson2JsonRedisSerializer)) .disableCachingNullValues(); RedisCacheManager cacheManager = RedisCacheManager.builder(factory) .cacheDefaults(config) .build(); return cacheManager; } }
(4)测试类
@RestController @RequestMapping("/redis") public class Controller { @Resource private RedisTemplate redisTemplate; @GetMapping public String m1(){ redisTemplate.opsForValue().set("name","ycl"); String name = (String) redisTemplate.opsForValue().get("name"); return name; } }