Redis系列:
什么是Redis
Redis 是一个开源(BSD许可)的,内存中的数据结构存储系统,它可以用作数据库、缓存和消息中间件。 它支持多种类型的数据结构,如字符串(string)、散列(hash)、列表(list)、集合(set)、有序集合(sorted set)与范围查询、bitmaps、 hyperloglogs 和地理空间(geospatial) 索引半径查询。Redis内置了复制(replication),Lua脚本(Lua scripting),LRU驱动事件(LRU eviction),事务(transactions)和不同级别的磁盘持久化(persistence), 并通过 Redis Sentinel 和自动 Redis Cluster 提供高可用性(high availability)。
Redis 支持很多特性,例如将内存中的数据持久化到硬盘中,使用复制来扩展读性能,使用分片来扩展写性能。
Redis 优势
- 性能极高:Redis能读的速度是110000次/s,写的速度是81000次/s
- 丰富的数据类型:Redis支持二进制案例的 Strings, Lists, Hashes, Sets 及 Ordered Sets 数据类型操作
- 原子:Redis的所有操作都是原子性的,意思就是要么成功执行要么失败完全不执行。单个操作是原子性的。多个操作也支持事务,但不保证原子性
- 丰富的特性:Redis还支持 publish/subscribe、通知、key 过期等特性
Redis 能做什么?
开发人员都只带Redis可以用来做缓存,除了缓存以外还可以做什么?
下面来自老钱的 Redis 深度历险:核心原理与应用实践
- 记录帖子的点赞数、评论数和点击数 (hash)。
- 记录用户的帖子 ID 列表 (排序),便于快速显示用户的帖子列表 (zset)。
- 记录帖子的标题、摘要、作者和封面信息,用于列表页展示 (hash)。
- 记录帖子的点赞用户 ID 列表,评论 ID 列表,用于显示和去重计数 (zset)。
- 缓存近期热帖内容 (帖子内容空间占用比较大),减少数据库压力 (hash)。
- 记录帖子的相关文章 ID,根据内容推荐相关帖子 (list)。
- 如果帖子 ID 是整数自增的,可以使用 Redis 来分配帖子 ID(计数器)。
- 收藏集和帖子之间的关系 (zset)。
- 记录热榜帖子 ID 列表,总热榜和分类热榜 (zset)。
- 缓存用户行为历史,进行恶意行为过滤 (zset,hash)。
为什么 Redis是单线程模型,还会达到每秒万级别的处理能力?
1、内存访问,Redis 将所有数据放到内存中,内存的响应时长大约为100纳秒,这是 Redis 达到每秒万级别访问的重要基础;
2、非阻塞 I/O,Redis 使用 epoll 作为 I/O 多路复用技术的实现,再加上 Redis 自身的事件处理模型将 epoll 中的连接、读写、关闭都转化为事件,不在网络 I/O 上浪费事件;
- 阻塞 IO: 资源不可用时,IO 请求一直阻塞,直到反馈结果(有数据或超时)
- 非阻塞 IO:资源不可用时,IO 请求离开返回,返回数据标识资源不可用
3、单线程避免了线程切换和竞争产生的消耗。
安装Redis
详细的教程这里就不写了,给篇 参考文献
Redis基本类型
只讲一些常用的,详细的可以去官网查看。
String
基本命令
1 | SET key value 设置指定 key 的值 |
对于字符串类型的保存,上面的知识简单的,如果你在终端中保存,它提示的命令其实不止是上面看到的。set key value [EX seconds] [PX milliseconds] [NX|XX]
,这才是它所提供全部的命令。不过从这个命令中可以看出,在后来版本的Redis中,基本上 set
命令取代了 setnx
- EX/PX: EX 指的是秒数;PX 指的是毫秒
- NX/XX:NX 表示当key不存在时,创建保存;XX 表示当key存在时,保存value
Hash
1 | HDEL key field1 [field2] 删除一个或多个哈希表字段 |
List
Redis 列表是简单的字符串列表,按照插入顺序排序,元素可以重复。
1 | LINDEX key index 通过索引获取列表中的元素 |
- 队列(lpop):右边进左边出
- 栈(rpop):右边进右边出
Set
Redis 的 Set 是 String 类型的无序集合。集合成员是唯一的,这就意味着集合中不能出现重复的数据。
1 | SADD key member1 [member2] 向集合添加一个或多个成员 |
ZSET
Redis 有序集合和集合一样也是 String 类型元素的集合,且不允许重复的成员。它是一个 Set,保证了内部 value 的唯一性,另一方面,它可以给每个 value 赋予一个 score,代表这个 value 的排序权重,在 score 相同的情况下,内部还会按照 value 的大小进行排序。它的内部实现用的是一种叫做「跳跃列表」的数据结构。
1 | ZADD key score1 member1 [score2 member2] 向有序集合添加一个或多个成员,或者更新已存在成员的分数 |
新增的一些新类型
HyperLogLog
HyperLogLog 是用来做基数统计的。HyperLogLog 的优点是,在输入元素的数量或者体积非常非常大时,计算基数所需的空间总是固定的、并且是很小的,因此每个 HyperLogLog 键只需要花费 12 KB 内存,就可以计算接近 264 个不同元素的基数。
HyperLogLog 提供了两个指令 pfadd
和 pfcount
,根据字面意义很好理解,一个是增加计数,一个是获取计数。pfadd 用法和 set 集合的 sadd 是一样的,来一个用户 ID,就将用户 ID 塞进去。pfcount 和 scard 用法是一样的,直接获取计数值。
缺点:
- 精确度。对于数据量大的时候,会出现精确度缺失。
- HyperLogLog 这个数据结构不是免费的,不是说使用这个数据结构要花钱,它需要占据一定 12k 的存储空间,所以它不适合统计单个用户相关的数据。如果你的用户上亿,可以算算,这个空间成本是非常惊人的。但是相比 set 存储方案,HyperLogLog 所使用的空间那真是可以使用千斤对比四两来形容了。
1 | pfadd key element [element ...] //增加 |
GeoHash
Redis 在 3.2 版本以后增加了地理位置 GEO 模块,意味着我们可以使用 Redis 来实现摩拜单车「附近的 Mobike」、美团和饿了么「附近的餐馆」这样的功能了。
1 | //添加 |
其他功能
Pub/Sub
订阅发布功能
Transaction(事务)
Redis 事务功能
Jedis
官网上推荐使用Jedis来操作Redis的。
1 | public static void main(String[] args) { |
不过,在平时开发中,我们一般都会基于Spring提供的Redis操作进行Redis。我自己练习的时候源码,有兴趣的话可以去下载来看看,这是一个基于springboot的项目,里面集成了很多东西。