- 几种数据类型
- 底层数据结构
- 三种部署模式
- 持久化
- 分布式锁的设计
- 应用场景
几种数据结构
bitmap
- 原理:我们知道,在计算机中,所有的数据都是用0和1来表示的,也就是一个个的比特位,1KB=1000B=8000bit,也就是说存储结果只有0和1的数据,用比特位存储的话,8000个用户的数据只需要1KB存储空间就可以了。bitmap的原理就是这样的:用bit去存储数据,但是这里的数据只能有两种结果0和1。
- 用法:
1、setbit:setbit key offset value
设置key的offset位置的值,key是键,offset是下标偏移量,value是值(只有0和1);
2、getbit:getbit key offset
获取key的offset位置上的值;
3、bitcount key [start end]
统计key上值为1的数据,start和end下标可选,end为-1时表示结束下标不限;
4、bitop operation destkey key [key …]
运算bitmap数据,operation是运算类型有AND、OR、NOT、XOR(与、或、非、异或) - 使用场景:
1、签到:签到有两种使用场景,一种是按天来生成一个bitmap,用户id为下标来统计每天签到的情况,另外一种是按每个用户来生成bitmap,每天为下标来统计每个用户的签到情况,如果想要看某个客户的签到情况,直接bigcount就行了,很方便;
2、在线状态:其实和签到原理是一样的,记录状态0和1就行了,就不细说了。 - 坑:
1、存储空间:bitmap本质上是string类型,也就是说最大是512M,能表示的最大位数是2^32,它是按需去扩容的,如果存储数据的下标很分散,那它会迅速扩容,占用内存;
2、bitcount的坑:bitcount的下标不是以bit为单位,而是是Byte为单位的,也就是说bitcount的下标转换成bitmap的下标要乘以8,举个例子:bitcount bit_test 0 2,表示的是统计下标0到下标23的数据。
布隆过滤器
布隆过滤器不是一种新的数据类型,本质上是bitmap,但是其实要说本质的话,redis只有五种基本的数据类型,其他的数据类型都是这五种封装出来的。
- 使用场景:现在有一个大小为100G的集合,需要判断一个元素是否在这个集合,需要怎么做?这个大量的数据存到数据库肯定会影响查询效率,存到redis中需要100G的内存,不太现实,这个时候就可以用到布隆过滤器了,布隆过滤器可以判断出一个元素一定不存在,可能存在;
- 原理:跟Hash表类似,先将集合中的元素进行hash运算得到hash值,然后将hash值作为下标,将bitmap对应的位置标记为1,表示这个位置有元素了,当进行元素对比的时候,只需要将要对比的元素进行hash运算,得到hash值看bitmap对应位置的值是否为1就行了,根据hash运算的特点:相同元素的hash值一定相同,不同元素的hash值不一定不相同,可以推测出:如果这个位置的值是0的话,这个元素一定在集合中不存在,但是如果为1的话,则不能说明这个元素一定在元素中存在。
- 优点:占用空间少,查询速度快,是O(1)级别的;
- 缺点:对存在具有一定的误判率,且数据量越大误判率越高(发生碰撞的几率越高),但是也可以加大bitmap的容量来减小碰撞的几率;不能删除已添加的数据;
- 实际应用:
1、防止缓存穿透攻击:攻击者会不断地去请求一个不存在的数据,使每次请求都越过缓存直接打到数据库,从而拖垮数据库,这个就是缓存穿透攻击,为了防止这种攻击,可以把这个不存在的数据也存到缓存中,这样下次请求就不会到数据库了,但是这样保存下来的数据量会逐渐变大,这个时候就可以使用布隆过滤器来保存这个数据,如果存在就直接访问缓存返回数据,不存在就访问数据库,并加到布隆过滤器中;
2、黑名单:因为布隆过滤器存在误判,所以最好使用在允许存在误判的业务场景,像垃圾邮件,可疑操作等等。
geo
这个是存储坐标的API,这个业务场景太特殊了,一般不会用到。
- 用法:
1、geoadd:增加某个地理位置的坐标
命令:geoadd key longitude latitude member [longitude latitude member …]
说明:key:整个值的key,longitude:经度,latitude:纬度,member:这个坐标的名称,可以同时添加多个。
例:geoadd members 70 70 member3 50 50 member4
2、geopos:获取某个地理位置的坐标
命令:geopos key member [member …]
说明:key:整个值的key,member:这个坐标的名称,跟geoadd命令对应。
例:geopos members member1 member2
3、geodist:获取两个地理位置的距离
命令:geodist key member1 member2 [unit]
说明:key:整个值的key,member1、member2:这个坐标的名称,跟geoadd命令对应,unit是距离单位,m 表示单位为米、km 表示单位为千米、mi 表示单位为英里、ft 表示单位为英尺,默认是m。
例:geodist members member1 member2 m
4、georadius:根据一个坐标来获取一定范围内的地理位置集合
命令:georadius key longitude latitude radius m|km|ft|mi [WITHCOORD] [WITHDIST] [WITHHASH] [COUNT count] [ASC|DESC] [STORE key] [STOREDIST key]
说明:key:整个值的key,longitude:经度,latitude:纬度,radius:范围值,m|km|ft|mi:单位,后面的是返回的数据格式。
例:georadius members 60 60 100 m
5、georadiusbymember:根据一个成员坐标来获取一定范围内的地理位置集合
命令:georadiusbymember key member radius m|km|ft|mi [WITHCOORD] [WITHDIST] [WITHHASH] [COUNT count] [ASC|DESC] [STORE key] [STOREDIST key]
说明:就是把georadius中的经纬度换成一个成员坐标了,这个里面的值也包括自己。
例:georadiusbymember members member1 100 m
6、geohash:获取坐标的hash值
命令:geohash key member [member …]
说明:没什么好说的。
例:geohash members member1
hypeloglog
这个数据类型主要的作用是用很少的空间来完成大量的数据统计,用在日志分析和流量统计比较多,它不会保存数据本身,具体实现原理我也没太看明白。。。
- 用法:
1、pfadd:添加元素,可以添加多个,具有唯一性,相同的元素不会重复添加
命令:pfadd key element [element …]
例:pfadd log zhangsan
2、pfcount:统计元素个数
命令:pfcount key [key …]
例:pfcount log
3、pfmerge:合并多个hypeloglog
命令:pfmerge destkey sourcekey [sourcekey …]
说明:destkey:生成的新的hypeloglog,sourcekey:原hypeloglog
例:pfmerge log2 log log1