从0到1快速了解Redis数据库
文章目录
- 一、什么是Redis?
- 二、Redis的相关特性
- 三、Redis中的数据类型
- 四. Redis中数据的内部编码
- 五、 渐进式遍历
- 六、为什么Redis读写性能高?
一、什么是Redis?
Redis(Remote Dictionary Server)是基于内存的仅存储键值对的开源内存数据库(组件)。因其高性能,也就是读写速度快、简单易用而闻名业界。虽然它不像MySQL这种关系型数据库支持多种复杂的数据库查询操作,但架不住它实在是"太快了"(每秒可处理数十万次操作),在高并发场景下应用广泛。至于为什么Redis性能如此之高,下文会介绍到。
此外它还支持持多种数据结构,例如Map\Set\List等,适合多种场景,比如缓存、排行榜、会话存储 、消息队列、分布式锁、实时分析与统计…
二、Redis的相关特性
- 内存存储:数据存在内存中,天然读写速度要比在硬盘的读写速度快。
- 持久化:虽然是内存数据库,Redis支持将数据写入磁盘(RDB快照和AOF日志),防止数据丢失。
- 高性能:单线程模型(后面会详细讲)避免了线程切换开销,性能极高。
- 丰富的数据类型:虽然全局存储Key-Value形式的字符串(类似HashMap),但Key—Value中的Value支持多种复杂数据结构(等一下也会讲到)。
- 发布/订阅:支持消息队列功能,适合实时应用。
- Lua脚本:支持自定义脚本,增强灵活性。
三、Redis中的数据类型
Redis 中的Key-Value中的Value支持以下五种常用的数据类型:
- String(字符串):最基本类型,可以存文本、数字甚至二进制数据。比如存储用户ID、计数器等。
- List(列表):这里的列表更像是双端队列Deque,头尾都可以进出,在早期Redis就是用List来实现消息队列的。
- Set(集合):无序且不重复的字符串集合,适合去重、交集并集操作。比如存储用户标签。
- Sorted Set(有序集合):每个元素带有分数的集合,自动按分数排序,适合排行榜。
- Hash(哈希):键值对的集合,适合存储对象,比如用户信息。类似于Java中的HashMap
此外还有三种特定场景下用到的数据类型:
- Bitmap(位图):操作二进制位,适合统计活跃用户等场景。
- HyperLogLog:判断给定集合中有多少不同的元素。这种类型占用内存非常非常少,但缺点是无法知晓集合中有那些元素。
- Geo(地理位置):支持存储经纬度,计算距离,适合位置服务。
Redis中所有的数据都支持设定过期时间,到达过期时间,该数据(键值对)自动会被删除。
Redis的过期删除策略主要包括以下三种方式:
- 惰性删除:键过期后不立即删除,而是在访问该键时检查是否过期,若过期则删除,则删除,返回nil(类似于null,表示空)优点是节省CPU资源,缺点是可能存在部分过期键未被及时删。
- 定期删除:Redis每隔一段时间(默认100ms)随机抽查部分设置了过期时间的键,删除其中已过期的键,减少内存占用,平衡性能和清理效率,但是CPU占用多。
Redis通常结合惰性删除和定期删除两种过期删除策略,以在内存管理和性能之间取得平衡。
四. Redis中数据的内部编码
标题三中讲的数据类型是逻辑上的数据类型。但实际Redis为了提升性能,不同的数据类型会因为存储的实际数据规模大小使用最优的编码进行存储。
数据类型 | 内部编码 | 编码选择依据 |
---|---|---|
字符串 (String) | int (整数)embstr (短字符串)raw (长字符串) | 根据内容和长度自动选择: 整数使用 int ;短字符串(≤44字节)使用 embstr ;长字符串使用 raw 。 |
哈希 (Hash) | ziplist (压缩列表)hashtable (哈希表) | 元素少且键值对长度短时使用 ziplist 节省内存;元素多或键值对长度超阈值时使用 hashtable 提高效率。 |
列表 (List) | ziplist (压缩列表)linkedlist (双向链表) | 根据元素数量和大小选择: 小规模数据使用 ziplist ;大规模数据使用 linkedlist (从Redis3.2开始List内部编码开始统一使用quicklist ,这个类型在减少内存占用的同时,提升了读写性能 )。 |
集合 (Set) | intset (整数集合)hashtable (哈希表) | 元素为整数且数量少时使用 intset ;元素为非整数或数量多时使用 hashtable 。 |
有序集合 (Sorted Set) | ziplist (压缩列表)skiplist (跳跃表) | 元素少时使用 ziplist 节省内存;元素多时使用 skiplist 提升性能。 |
这些具体的编码方式由 Redis 自动管理,用户无需干预。
五、 渐进式遍历
由于Redis使用的单线程模型,也就是处理读写指令只会使用一个线程执行,因此如果一条指令执行时间过长,一定会出现阻塞现象,导致性能下降。为了避免这种情况发现,Rdis提供了渐进式遍历(scan)这样一个功能。
渐进式遍历顾名思义,慢慢遍历。感觉遍历的时间长了,redis服务器就停下,去干别的事(处理其他读写请求),过一会儿再回来遍历没有遍历的内容,循环往复直到遍历完所有内容(当然,也可以中途停止遍历,Redis服务器不会受到影响)。
Redis提供了一组名字为Scan的命令,去执行渐进式遍历,命令的具体用法可以查看官方文档:Redis官方文档-命令
六、为什么Redis读写性能高?
- 使用内存进行存储,天然比硬盘读写要快不少。
- Redis的查询功能相对其他的关系型数据库要简单一些,因此执行开销相对来讲也会少一些。
- Redis使用的单线程模型处理每一个读写请求,避免因为多线程导致的线程竞争开销。
- Redis和MySQL一样是客户端-服务器结构的。Redis在处理接收网络请求上,使用了epoll机制,以及引入多线程,去接收多个Socket中的读写请求(一个线程管理多个Scoket),也就是IO多路复用,然后按顺序给到Redis服务器执行读写命令的线程执行。
关于Redis读写相关命令可以查看Redis官方文档
如果嫌麻烦可以看博主自己整理的一些Redis常用命令。