关键词:
Redis
Redis是一个开源(BSD许可)的内存数据结构存储,用作数据库、缓存和消息代理。Redis提供数据结构,如strings, hashes, lists, sets, sorted sets with range queries, bitmaps, hyperloglogs, geospatial indexes, and streams.。Redis具有内置复制、Lua脚本、LRU eviction、事务和不同级别的磁盘持久性,并通过Redis Sentinel和Redis Cluster的自动分区提供高可用性。
一、Redis基本数据结构
1. 字符串 (String)
字符串类型是Redis中最为基础的数据存储类型,它在Redis中是二进制安全的,这意味着该类型可以接受任何格式的数据,如JPEG图像数据或json对象描述信息等。在Redis中字符串类型的value最多可以容纳的数据长度是512M。
常用命令:
- set key value 设置值
- get key 获取值
- getset 将给定的值设置进去,并返回旧值
- mget key1 key2… 获取一个或多个key的值
- setnx key value 当key不存在时才设置值
- incr key 将key存储的值+1
- incrby key increment 将 key 所储存的值加上给定的增量值(increment)
- decr key 将key存储的值-1
- decrby key increment 将 key 所储存的值减去给定的增量值(increment)
- strlen key 返回key所存储的字符串的长度
注意:
- 字符串append命令会使用更多的内存
- 整数共享:如果能使用整数,就尽量使用整数
- 整数精度问题:redis能保证16位精度,17-18位的大整数就会丢失精度
2. 散列(hash)
Redis中Hash类型可以看成句又String key和String value的map容器。所以该类型非常适合存储对象的信息。
常用命令:
- hset key field value
- hget key field
- hmset key field1 value1 [field2 value2 ] 同时set多个field值
- hmget key field1 [field2]
- hgetall key 获取key的所有值
- hincrby key field increment 给指定的key的field增加给定的增量值(increment)
- hkeys key 获取某个key的所有field
- hvals key 获取某个key的所有value
- hlen key 获取hash表中字段的数量
- hexists key field 查看hash表中的字段是否存在
- hdel key field1 [field2] 删除一个或多个hash表字段
3. 列表(list)
在Redis中,List类型是按照插入顺序排序的字符串链表。和数据库结构中的普通链表一样,可以在头部和尾部添加新的元素。在插入时如果键不存在,Redis将为该键创建一个新的链表。与此相反,如果链表中所有的元素均被移除,那么该键也会被从数据库中删除。
常用命令:
- lpush key value1 [value2] 将一个值或多个值插入到列表头部
- rpush key value1 [value2] 将一个值或多个值插入到列表尾部
- lrange key start stop 获取列表指定范围的元素
- lpop key 移出并获取列表中的第一个元素
- rpop key 移出并获取列表中的最后一个元素
- blpop key1 [key2 ] timeout 阻塞性的移出并获取列表的第一个元素,如果没有元素就会阻塞到超时或有元素为止
- brpop key1 [key2 ] timeout 阻塞性的移出并获取列表的最后一个元素,如果没有元素就会阻塞到超时或有元素为止
- lindex key index 通过索引位置获取列表中的元素
- llen key 获取列表长度
- lset key index value 通过索引位置设置值
- ltrim key start stop 对一个列表进行修剪,只保留指定区间的元素,区间外的都删除掉
4. 集合(Set)
Redis 的 Set 是 String 类型的无序集合。集合成员是唯一的,这就意味着集合中不能出现重复的数据。Redis 中集合是通过哈希表实现的,所以添加,删除,查找的复杂度都是 O(1)。集合中最大的成员数为 2^32 - 1
常用命令:
- sadd key member1 [member2] 向集合中添加元素
- scard key 获取集合的成员数
- sdiff key1 [key2] 返回第一个集合与其他集合之间的差异
- sinter key1 [key2] 返回给定所有集合的交集
- sunion key1 [key2] 返回给定集合的并集
- sismember key member 判断member元素是否是集合中的成员
- smembers key 返回集合中所有成员
- spop key 移除并返回集中中的一个随机元素
- srandmember key [count] 返回集合中一个或多个随机数
- srem key member1 [member2] 移除集合中一个或多个成员
5. 有序集合(sorted set)
Redis 有序集合和集合一样也是 string 类型元素的集合,且不允许重复的成员。不同的是每个元素都会关联一个 double 类型的分数。redis 正是通过分数来为集合中的成员进行从小到大的排序。
常用命令:
- zadd key score1 member1 [score2 member2] 向有序集合中添加一个或多个成员,或更新已有成员的分数
- zcard key 获取有序集合中的成员数量
- zrange key start end [withscores] 通过索引区间返回有序集合中的成员
- zrevrange key start stop [WITHSCORES] 通过索引区间返回有序集合中的成员,分数从高到低
- zrangebyscore key min max [WITHSCORES] [LIMIT] 通过分数返回有序集合指定区间内的成员
- zrevrangebyscore key min max [WITHSCORES] [LIMIT] 通过分数返回有序集合指定区间内的成员,分数由高到低排序
- zrem key member [member …] 移除
- zremrangebyrank key start stop 移除给定排名区间的所有成员
- zremrangebyscore key min max 移除给定分数区间的所有成员
- zscore key member 返回有序集合中成员的分数
二、Redis的高级数据结构
1. HyperLogLog
Redis 在 2.8.9 版本添加了 HyperLogLog 结构。Redis HyperLogLog是用来做基数统计的算法,HyperLogLog的优点是,在输入元素的数量或者体积非常非常大时,计算基数所需的空间总是固定 的、并且是很小的。不过这个是估算,有一定的误差。
基数计算指的是统计一批元素中不重复元素的个数,比如UV的统计。实现基数统计最常见的是用Set这种数据结构。但是大数据量下Set会占用很大的存储空间。
常用命令:
- pfadd key element [element …] 添加指定元素到HyperLogLog 中
- pfcount key [key …] 返回给定key的基数估算值
- pfmerge destkey sourcekey [sourcekey …] 将多个hyperloglog 合为一个
2. GEO
Redis GEO主要用于存储地理位置信息,并对其进行操作。该功能在Redis3.2版本增加
常用命令:
- geoadd key longitude latitude member [longitude latitude member …] 添加地理位置坐标
- geopos key member [member …] 返回指定member的经纬度
- geodist key member1 member2 [m|km|ft|mi] 计算两个位置的距离 后面的是单位
m【米】 km【千米】 ft【英尺】 mi【英里】
-
georadius key longitude latitude radius m|km|ft|mi [WITHCOORD] [WITHDIST] [WITHHASH] [COUNT count] [ASC|DESC] [STORE key] [STOREDIST key] 以给定的经纬度为中心,返回键包含的元素中,与中心距离不超过给定最大距离的所有位置元素
-
georadiusbymember key member radius m|km|ft|mi [WITHCOORD] [WITHDIST] [WITHHASH] [COUNT count] [ASC|DESC] [STORE key] [STOREDIST key] 同上,只不过中心位置的传参由经纬度变成了member
-
geohash key member [member …] 获取一个或多个元素的geohash值
3. BitMap
BitMap的原理上一篇已经讲过了,它可以用作大数据量的存储,不过存储的内容只能是0或1. 可以使用在10亿用户的在线状态,1代表在线,0代表离线。
value值只能是0、1
- setbit key offset value
- getbit key offset
- bitcount key 获取值为1的个数
三、Redis 高级特性
1. Redis事务
Redis的事务与数据库的事务概念不同,Redis会将一个事务中的所有命令序列化,然后按顺序执行。Redis不可能在一个Redis事务的执行过程中插入执行另一个客户端发出的请求,事务中任意命令失败不影响其他命令的执行,也不会回滚。
2. 发布订阅
发布订阅是一种通信模式,发送者发送消息,订阅者接受消息。客户端可以订阅多个频道,然后有新消息发送给频道,订阅该频道的客户端就都能收到消息。
- subscribe channel [channel …] 订阅一个或多个频道
- psubscribe pattern [pattern …] 订阅一个或多个符合给定模式的频道
- publish channel message 将消息发送到指定通道
- unsubscribe [channel [channel …]] 退订给定的频道
- punsubscribe channel [channel …] 退订所有给定模式的频道。
3. 脚本
Redis 脚本通过Lua解释器来执行脚本,Redis 2.6 版本通过内嵌支持Lua环境
基本语法如下:
EVAL script numkeys key [key …] arg [arg …]
例子:
EVAL "return KEYS[1],KEYS[2],ARGV[1],ARGV[2]" 2 key1 key2 first second
4. Redis Stream
Redis Stream是5.0版本新增的数据结构。Redis Stream主要用于消息队列,Redis本身有一个发布/订阅功能,但是它有一个缺点,消息没有持久化,如果网络中断或宕机,数据就会丢失。
Redis Stream提供了消息的持久化和主备复制功能,它有一个消息链表,把所有加入的消息都串起来,每个消息都有唯一的ID和内容。
常用命令:
- xadd key ID field value [field value …] 添加消息
xadd mystream * name sa surname occc (*代表id由redis生成)
- xdel key ID [ID …] 删除消息
- xrange key start end [COUNT count] 查看消息
xrange mystream - + (- 代表最小值,+ 代表最大值)
- xgroup [CREATE key groupname id-or- ] [ S E T I D k e y g r o u p n a m e i d − o r − ] [SETID key groupname id-or- ][SETIDkeygroupnameid−or−] [DESTROY key groupname] [DELCONSUMER key groupname consumername] 创建消费者组
从头开始消费:
xgroup create mystream consumer-group-name 0-0
从尾部开始消费,只接受新消息
xgroup create mystream consumer-group-name $
- xreadgroup group group consumer [COUNT count] [BLOCK milliseconds] [NOACK] STREAMS key [key …] ID [ID …] 从消费者组读取消息
XREADGROUP GROUP consumer-group-name consumer-name COUNT 1 STREAMS mystream
第二个group :消费组名
consumer: 消费者名
count :读取数量
milliseconds : 阻塞毫秒数
key :队列名
ID:消息id
四、Redis使用场景
1. 业务数据缓存
- 通用数据缓存:String、list等
- 会话缓存、token、session缓存
2. 业务数据处理
- 非严格一致性要求的数据
- 业务操作去重:订单处理的幂等校验
- 业务数据排序
3. 全局一致计数
- 全局流控
- 秒杀时库存计算
- 全局ID生成
4. 高效统计计数
- id、ip等使用bitmap操作
- 使用HyperLogLog进行UV、PV等非精确性的统计
5. 发布订阅与Stream
用于消息发布订阅模式
6. 分布式锁
- 获取锁
set key my_random_value NX PX 30000
- 释放锁,需要用到lua脚本保证原子性
if redis.call("get",KEYS[1])==ARGV[1] then
return redis.call("del",KEYS[1])
else
return 0
end
五、Redis的Java客户端
1. Jedis
基于BIO、线程不安全,需要配置连接池管理连接
2. Lettuce
目前主流推荐的驱动,基于Netty NIO,API线程安全
3. Redission
基于Netty NIO,API线程安全。大量丰富的分布式功能,如分布式的基本数据类型和锁。
六、项目集成
1. SpringMvc项目可以引入Spring data redis
maven依赖
<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-redis</artifactId>
<version>2.1.2.RELEASE</version>
</dependency>
核心是RedisTemplate(可以配置基于Jedis、Lettuce、Redisson),封装了基本的redis命令。
2. SpringBoot接入(默认使用的Lettuce)
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
配置spring.redis
如:spring.redis.host=127.0.0.1
3. Spring Cache 集成Redis
- 启用Spring Cache
@EnableCaching
- 方法上添加缓存注解
@Override
@Cacheable(value = "userCache")
public User getUser(Integer id)
return userMapper.getUser(id);
- 配置redisCache
@Configuration
public class CacheConfig
@Bean
public RedisCacheManager cacheManager(RedisConnectionFactory redisConnectionFactory)
return RedisCacheManager.create(redisConnectionFactory);
番外:
- Redis到底是单线程,还是多线程?
这个问题有坑。首先Redis作为一个进程来讲是多个线程的。比如Redis通过多线程方式在后台删除对象、以及通过 Redis模块实现的阻塞命令等.单线程的地方在于探测哪个接收完了请求数据->数据处理->返回数据。而其他耗时操作是用了其他线程。
探测哪个客户端的请求接受完了,使用的是IO多路复用模型,“多路”是指多个网络连接,“复用”是复用同一个线程。
- 为什么IO模块在Redis6之前是单线程?
因为Redis是基于内存的操作,CPU不是瓶颈,瓶颈在于机器内存的大小或网络带宽。 - Redis6之后的多线程是什么?
IO模型使用了多线程的NIO模型,内存处理线程也还是单线程。
❤️爆肝新一代大数据存储宠儿,梳理了2万字“超硬核”文章!❤️(代码片段)
🍅作者:不吃西红柿🍅简介:CSDN博客专家🏆、信息技术智库公号作者✌。简历模板、职场PPT模板、技术难题交流、面试套路尽管【关注】私聊我。🍅欢迎点赞👍收藏⭐留言📝如有错误敬请指正&... 查看详情
❤️爆肝新一代大数据存储宠儿,梳理了2万字“超硬核”文章!❤️(代码片段)
🍅作者:不吃西红柿🍅简介:CSDN博客专家🏆、信息技术智库公号作者✌。简历模板、职场PPT模板、技术难题交流、面试套路尽管【关注】私聊我。🍅欢迎点赞👍收藏⭐留言📝如有错误敬请指正&... 查看详情
硬核!高频linux命令大总结,建议收藏~
点击上方蓝色“终端研发部”,选择“设为星标”学最好的别人,做最好的我们 ◆ 前言记得不久前跟大家大分享了一波个人在平时日常工作、学习、开发、写文字、做视频等过程中,一些好用高效的在线工具和网... 查看详情
hive从入门到精通,hql硬核整理四万字,全面总结,附详细解析,赶紧收藏吧!!(代码片段)
往期好文推荐:🔶🔷Hadoop深入浅出——三大组件HDFS、MapReduce、Yarn框架结构的深入解析式地详细学习【建议收藏!!!】🔶🔷Redis从青铜到王者,从环境搭建到熟练使用,看这一篇就够了... 查看详情
万字长文超硬核详细学习系列——深入浅出linux基础篇的知识点,值得你收藏学习必备(代码片段)
茫茫人海千千万万,感谢这一秒你看到这里。希望我的文章对你的有所帮助!愿你在未来的日子,保持热爱,奔赴山海!Linux基础篇目录1.Linux系统介绍1.1linux的概述1.2linux的优势1.3linux的分类1.4常见的发行版linux... 查看详情
万字长文超硬核详细学习系列——深入浅出linux高级篇的知识点,值得你收藏学习必备(代码片段)
茫茫人海千千万万,感谢这一秒你看到这里。希望我的文章对你的有所帮助!愿你在未来的日子,保持热爱,奔赴山海!Linux高级篇目录1.Linux的用户管理1.1添加用户1.2删除用户1.3查询用户信息1.4切换用户1.5对... 查看详情
熬夜爆肝万字c#基础入门大总结建议收藏(代码片段)
往期文章分享点击跳转=>熬夜再战Android从青铜到王者-UI组件快速搭建App界面点击跳转=>熬夜再战Android从青铜到王者-几个适配方案点击跳转=>熬夜再战Android从青铜到王者-开发效率插件篇点击跳转=>Unity粒子特... 查看详情
超硬核!万字梳理文本生成图像!
点击机器学习算法与Python学习,选择加星标精彩内容不迷路选自Intento,作者:GrigorySapunov机器之心编译目前多模态任务成为行业热点,本文梳理了较为优秀的多模态文本图像模型:DALL·E、CLIP、GLIDE、DALL·E2(unCL... 查看详情
超硬核!万字梳理文本生成图像!
点击机器学习算法与Python学习,选择加星标精彩内容不迷路选自Intento,作者:GrigorySapunov机器之心编译目前多模态任务成为行业热点,本文梳理了较为优秀的多模态文本图像模型:DALL·E、CLIP、GLIDE、DALL·E2(unCL... 查看详情
超硬核!万字梳理文本生成图像!
点击机器学习算法与Python学习,选择加星标精彩内容不迷路选自Intento,作者:GrigorySapunov机器之心编译目前多模态任务成为行业热点,本文梳理了较为优秀的多模态文本图像模型:DALL·E、CLIP、GLIDE、DALL·E2(unCL... 查看详情
❤️爆肝3万字,最硬核丨mysql知识体系命令全集建议收藏❤️(代码片段)
...赞👍收藏⭐留言 📝 🍅耗时1年整理,硬核文章目录:https 查看详情
万字详解spark开发调优(建议收藏)
1一、前言在大数据计算领域,Spark已经成为了越来越流行、越来越受欢迎的计算平台之一。Spark的功能涵盖了大数据领域的离线批处理、SQL类处理、流式/实时计算、机器学习、图计算等各种不同类型的计算操作,应用范... 查看详情
要看就看最好,16万字全网最硬核redis总结,谁赞成,谁反对?(被粉丝疯狂催更,已有人反馈看完专栏拿到大厂offer!!!)(代码片段)
我摊牌了,这篇文章,值得99%的人收藏!!!阅读时间较长,后续会设置成仅粉丝可见,建议收藏起来慢慢看!!!原创不易,千万不要白嫖,真香警告⚠️。本文评论区会送出两本... 查看详情
要看就看最好,16万字全网最硬核redis总结,谁赞成,谁反对?(被粉丝疯狂催更,已有人反馈看完专栏拿到大厂offer!!!)(代码片段)
我摊牌了,这篇文章,值得99%的人收藏!!!阅读时间较长,后续会设置成仅粉丝可见,建议收藏起来慢慢看!!!原创不易,千万不要白嫖,真香警告⚠️。本文评论区会送出两本... 查看详情
爆肝3万字,csdn最硬核mysql知识体系命令全集❤️速查手册,建议收藏❤️(代码片段)
...赞👍收藏⭐留言 📝 🍅耗时1年整理,硬核文章目录:https: 查看详情
❤️万字长文总结❤️一篇学会redis高可用✔集群✔搭建详细教程(代码片段)
大家好,我是Lex喜欢欺负超人那个Lex擅长领域:python开发、网络安全渗透、Windows域控Exchange架构今日重点:今天总结一下Redis集群高可用的搭建流程【惊喜推荐+优质资源见文末,建议收藏!!!】建... 查看详情
❤️万字长文总结❤️一篇学会redis高可用✔集群✔搭建详细教程(代码片段)
大家好,我是Lex喜欢欺负超人那个Lex擅长领域:python开发、网络安全渗透、Windows域控Exchange架构今日重点:今天总结一下Redis集群高可用的搭建流程【惊喜推荐+优质资源见文末,建议收藏!!!】建... 查看详情
史上最全wireshark使用教程,8万字整理总结,建议先收藏再耐心研读
目录第 1 章 介绍...11.1. 什么是Wireshark.11.1.1. 主要应用...11.1.2. 特性...11.1.3. 捕捉多种网络接口...21.1.4. 支持多种其它程序捕捉的文件...21.1.5. 支持多格式输出...21.1.6. 对多种协议解码提供支持...21.1.7. 开源软件...21.1.8. Wire... 查看详情