1.Redis 特殊数据结构
1.Streams
- 应用场景:主要用为队列(阻塞队列)
2.Geospatial
- 应用场景:用来存储坐标(经纬度)
3.HyperLogLog
- 应用场景:估算集合中的元素个数
- 注意:
HyperLogLog
不存储元素的内容,但是能够记录“元素的特征”,从而在新增元素的时候,能够知道当前新增的元素,是一个已经存在的元素还是一个崭新的元素- 也就是说,
HyperLogLog
只能用来计数,记录当前集合中有多少个不同的元素,但是不能告诉用户这些元素都是啥 HyperLogLog
存储元素的时候,提取特征的过程是不可逆的
- 优势举例:
Set
可以统计服务器的UV,假设Set
存储userId
,每个8字节,存储1亿个UV,则需要大概800MB,但是HyperLogLog
只需要最多使用12KB空间,就可以实现上述效果
4.bitmaps
- 应用场景:使用
bit
位来表示整数,本质上还是一个集合,属于是Set
类型对整数的特化版本
5.bitfields
- 理解:就是C中说到的位段,这里称为位域
2.渐进式遍历
1.是什么?
-
Redis使⽤
scan
命令进⾏渐进式遍历键,进⽽解决直接使⽤keys
获取键时可能出现的阻塞问题。 -
每次
scan
命令的时间复杂度是 O ( 1 ) O(1) O(1),但是要完整地完成所有键的遍历,需要执⾏多次scan
- ⾸次
scan
从0开始 - 当
scan
返回的下次位置为0时,遍历结束
- ⾸次
-
注意:这里的渐进式遍历,在遍历过程中,不会在服务器这边存储任何的状态信息,此处的遍历,随时都可以终止,不会对服务器产生任何的副作用
-
渐进式遍历其实是一组命令,这一组命令的使用方法是一样的,其中的代表是
SCAN
2.SCAN
- 功能:以渐进式的方式进行键的遍历
- 语法:
SCAN cursor [MATCH pattern] [Count count] [Type type]
count
:只是一个给Redis服务器的"提示/建议",写入的count
和实际返回的key
的个数不一定是完全相同的,但是不会差很多
- 返回值:
- 下一次
scan
的游标cursor
-> 下次继续遍历,光标要从哪里开始cursor
不能理解成下标,不是一个连续递增的整数,仅仅就是一个"字符串"
- 以及本次得到键
- 下一次
- 时间复杂度: O ( 1 ) O(1) O(1)
- 注意:渐进性遍历
scan
虽然解决了阻塞的问题,但如果在遍历期间键有所变化(增加、修改、删除),可能导致遍历时键的重复遍历或者遗漏,这点务必在实际开发中考虑 - 说明:除了
scan
以外,Redis面向哈希类型、集合类型、有序集合类型分别提供了hscan
、sscan
、zscan
命令,用法和scan
基本类似
3.数据库管理
- Redis提供了⼏个⾯向Redis数据库的操作,分别是
dbsize
、select
、flushdb
、flushall
1.切换数据库
-
语法:
select dbIndex
-
说明:
- 许多关系型数据库,例如MySQL⽀持在⼀个实例下有多个数据库存在的,但是**与关系型数据库⽤字符来区分不同数据库名不同,Redis只是⽤数字作为多个数据库的实现**
- Redis默认配置中是有16个数据库。
select 0
操作会切换到第⼀个数据库,select 15
会切换到最后⼀个数据库 - 0号数据库和15号数据库保存的数据是完全不冲突的,即各种有各⾃的键值对。默认情况下,我们处于数据库0
-
注意:Redis中虽然⽀持多数据库,但随着版本的升级,其实不是特别建议使⽤多数据库特性
- 如果真的需要完全隔离的两套键值对,更好的做法是维护多个Redis实例,⽽不是在⼀个 Redis实例中维护多数据库
- 这是因为本⾝Redis并没有为多数据库提供太多的特性
- 其次⽆论是否有多个数据库,Redis都是使⽤单线程模型,所以彼此之间还是需要排队等待命令的执⾏
- 同时多数据库还会让开发、调试和运维⼯作变得复杂
- 实践中,始终使⽤数据库0其实是⼀个很好的选择
- 如果真的需要完全隔离的两套键值对,更好的做法是维护多个Redis实例,⽽不是在⼀个 Redis实例中维护多数据库
2.清除数据库
flushdb / flushall
命令⽤于清除数据库,区别:flushdb
:只清除当前数据库flushall
:会清除所有数据库
- 永远不要在线上环境执⾏清除数据的操作,除非想”从删库到跑路“😛