Redis 是一个开源(BSD许可)的,内存中的数据结构存储系统,它可以用作数据库、缓存和消息中间件。 它支持多种类型的数据结构,如 字符串(strings), 散列(hashes), 列表(lists), 集合(sets), 有序集合(sorted sets) 与范围查询, bitmaps, hyperloglogs 和 地理空间(geospatial) 索引半径查询。 Redis 内置了 复制(replication),LUA脚本(Lua scripting), LRU驱动事件(LRU eviction),事务(transactions) 和不同级别的 磁盘持久化(persistence), 并通过 Redis哨兵(Sentinel)和自动 分区(Cluster)提供高可用性(high availability)。
五大基本数据类型 Redis-Key# 查看所有Key keys * # 设置key-value set key zzysy # 判断是否存在key exists key # 移动key到某个数据库 move key 1 # 切换数据库 select 1 # 得到value get key # 设置过期时间,单位是秒 expire key 10 # 查看过期时间 ttl key # 查看key的类型 type key # 查看数据库所有的key key * # 清空当前数据库 flushdb # 清空全部数据库 flushallString(字符串)
###############################################################
# set key zzysy
# 追加字符串(如果key不存在,相当于set key)
append key "hello"
# 获取字符串长度
strlen key
###############################################################
# key加1,i++
incr key
# key减1,i--
decr key
# key加n,i+=n
incrby key 10
# key减n,i-=n
decrby key 10
###############################################################
# 截取字符串,[0,n]
getrange key 0 3
# 截取全部字符串
getrange key 0 -1
# 替换字符串某个范围的值,abcdefg->axxxxxx
setrange key 1 xxxxxx
###############################################################
# 设置key-value,并设置过期时间,setex key 过期时间 value
setex key 30 hello
# 如果key不存在,创建key-value,如果存在key,创建失败(在分布式锁中常常使用)
setnx key hello
###############################################################
# 批量设置key-value
mset k1 v1 k2 v2 k3 v3
# 批量获取key
mget k1 k2 k3
# 批量mset,原子性(要么一起成功要么一起失败),k1存在,k4不存在,但是都不创建
msetnx k1 v1 k4 v4
###############################################################
# 对象
# 设置一个user:1 对象,值为json字符串来保存一个对象
set user:1{name:zzy,age:20}
# 这里的key是一个巧妙的设计:user:{id}:{filed},
mset user:1:name zzy user:1:age 20
mget user:1:name user:1:age
###############################################################
# 先get再set,如果不存在值,则返回nil,再设置值,如果存在值,则获取原来的值,再设置值
getset key zzy #--->nil
get key #--->zzy
getset key ysy #--->zzy
get key #--->ysy
###############################################################
String类型的使用场景(value除了是我们的字符串还可以是数字):
计数器统计多单位的数量粉丝数对象缓存存储 List
基本的数据类型,列表在redis里面,可以把List可以玩成栈,队列,阻塞队列所有的List命令都是由L开头的
# 将一个值或多个值插入到list的头部(左) Lpush list one # 将一个值或多个值插入到list的尾部(右) Rpush list two # 获取list中的值 Lrange list 0 -1 # 通过区间获取具体的值 Lrange list 0 3 # 从头部移除list中的第一个值(左) Lpop list # 从尾部移除list中的第一个值(右) Rpop list # 获取指定下标的值 Lindex list 1 # 获取list的长度 Llen list # 移除list中指定个数的值(移除list中值为one的1个值) Lrem list 1 one # 截取list中指定区间的值,区间内保留,剩下的删除,[1,2] Ltrim list 1 2 # 移动list1中的尾部的值到list2头部 RpopLpush list1 list2 # 修改list中指定下标的值,如果list或下标不存在会error Lset list 1 666 # 在list中指定值的前面或后面插入值 Linsert list before world hello Linsert list after hello world
List小结:
它实际上是一个链表,双向链表,left,right都可以插入值如果key不存在,创建新的链表如果key存在,新增内容如果移除了所有的值,空链表,代表不存在在两边插入或者改动值,效率最高既可以作为队列,也可以作为栈 Set
set中的值不能重复
# 往set中添加值 Sadd set one # 查看set中的值 Smembers set # 判断某一个值是否在set中 Sismember set one # 获取set中值的个数 Scard set # 移除set中的指定值 Srem set one # 随机抽选出set中的一个值 Srandmember set # 随机抽出set中指定个数的值 Srandmember set 2 # 随机删除set中的值 Spop set # 将一个指定的值移动到另一个set中 Smove set1 set2 one # 查看两个set的差集 Sdiff set1 set2 # 查看两个set的交集 Sinter set1 set2 # 查看两个set的并集 Sunion set1 set2Hash(哈希)
Map集合,key-Map集合,这时候这个值是一个Map集合,本质和String类型没有太大区别,还是一个简单的key-valueHash更适合存储对象,Strng更适合存储字符串
# set一个key-value Hset hash field zzy # 获取一个key的value Hget hash field # set多个key-value Hmset hash field1 hello field2 world # 获取多个key的value Hmget hash field1 field2 # 获取全部的key-value Hgetall hash # 删除hash中指定的key-value Hdel hash field1 # 获取hash中有多少个key-value Hlen hash # 判断hash中指定key是否存在 Hexists hash field1 # 获取hash中所有的key Hkeys hash # 获取hash中所有value Hvals hash # 对应key的value加1 Hincr hash field1 # 对应key的value加n Hincrby hash field1 10 # 对应key的value减1 Hdecr hash field1 # 对应key的value减n Hdecrby hash field1 10 # 如何key不存在,创建key-value Hsetnx hash field1 helloZset(有序集合)
在set的基础上增加了一个值,set–>k1,v1,zset–>k1,score1,v1
# 添加一个/多个值,Zadd set score value Zadd set 1 one Zadd set 2 two 3 three # 获取全部值 Zrange set 0,-1 # 根据score正序排序,得到value的排名,-inf +inf是score的范围 Zrangebyscore set -inf +inf # 根据score正序排序,得到value的排名并附带score,-inf +inf是score的范围 Zrangebyscore set -inf +inf withscores # 根据score倒序排序,得到value的排名,-inf +inf是score的范围 Zdev rangebyscore set -inf +inf # 根据score倒序排序,得到value的排名并附带score,-inf +inf是score的范围 Zdevrangebyscore set -inf +inf withscores # 移除指定的value Zrem set one # 获取Zset中的元素个数 Zcard set # 获取指定区间的元素个数 Zcount set 0,2
其余的一些api,可以通过官网的官方文档查看
三种特殊数据类型 geospatial 地理位置朋友定位、附近的人、打车距离计算
Redis的Geo在Redis在3.2版本就推出了,这个功能可以推算地理位置的信息,两地之间的距离,方圆几里的人
可以查询一些测试数据http://www.jsons.cn/Ingcodeinfo/0706D99C19A781A3/
命令:
官方文档:https://www.redis.net.cn/order/3685.html
geoadd:
# 添加地理位置 # 规则:两级无法直接添加,我们一般会下载城市地理数据,通过java程序一次性导入 # 参数:key 值(纬度,经度,名称) geoadd china:city 116.40 39.90 beijing geoadd china:city 121.47 31.23 shanghai geoadd china:city 106.50 29.53 chongqing 114.05 22.52 shenzhen geoadd china:city 120.16 30.24 hangzhou 108.96 34.26 xian
geopos:
# 获取指定城市的经度和纬度 geopos china:city beijing geopos china:city shanghai guangzhou
geodist:
两人之间的距离
单位:
m 表示单位为米。km 表示单位为千米mi 表示单位为英里ft 表示单位为英尺
# 获取两地的距离,后面是单位 geodist china:city beijing shanghai geodist china:city beijing chongqing km
georadius:
我附近的人(获得所有附近的人的地址,定位),通过半径来查询
# 以给定的经纬度为中心,找出某一半径内的元素 # key 经度 纬度 半径 单位 withdist(显示距离) withcoord(显示经度纬度) count n(限制查询数量) georadius china:city 110 30 1000 km georadius china:city 110 30 1000 km withdist withcoord count 1
georadiusbymember:
# 以给定元素为中心,找出某一半径内的元素 georadiusbymember china:city beijing 1000 km
geohash:
返回一个或多个位置元素的Geohash表示
# 将二维的经纬度转换为一维的字符串,如果两个字符串越接近,那么距离越近 geohash china:city beijing chongqing
geo 底层实现原理其实就是Zset,我们可以使用Zset命令来操作geo:
# 查看地图中全部元素 Zrange china:city 0 -1 # 移除指定元素 Zrem china:city beijing ......Hyperloglog
什么是基数?
A(1,3,5,7,8,7) B(1,3,5,7,8)
基数(不重复的元素) = 5,可以接受误差
简介
redis2.8.9版本就更新了Hyperloglog数据结构
hyperloglog 基数统计算法
优点:
占用的内存是固定的,2^64不同的元素的基数,只需废12kb的内存,如果从内存角度比较的话,hyperloglog就是首选
网页UV:(一个人访问网站多次,还是算作一个人)
传统的方式:set保存用户id,就可以统计set中的元素数量作为标准判断,这个方式如果保存大量的用户id,就会比较麻烦,我们的目的是为了计数,而不是为了保存用户id
测试
如果允许容错,那么一定可以使用hyperloglog
如果不允许容错,那么使用set或者自己的数据类型
127.0.0.1:6379> PFadd key1 a b c d e f g #创建第一组hyperloglog key1 (integer) 1 127.0.0.1:6379> PFcount key1 #统计第一组key1的基数数量 (integer) 7 127.0.0.1:6379> PFadd key2 e f g h i j k #创建第二组hyperloglog key2 (integer) 1 127.0.0.1:6379> PFcount key2 #统计第二组key2的基数数量 (integer) 7 127.0.0.1:6379> PFmerge key3 key1 key2 #合并第一组和第二组到key3 (integer) 1 127.0.0.1:6379> PFcount key3 #统计第三组key3的基数数量,相当于key1和key2的基数 (integer) 11Bitmap
位存储
统计疫情感染人数,0000100001010101(感染是1,未感染是0)统计用户信息,活跃,不活跃,365天打卡两个状态的需求,都可以使用bitmapbitmap 位图,数据结构,所有都是操作二进制位来进行记录,只有0和1两个状态365天打卡情况 = 365bit 1字节 = 8bit 46个字节
测试
#七天打卡 127.0.0.1:6379> setbit sign 0 1 # 周一 打卡 1 (integer) 0 127.0.0.1:6379> setbit sign 1 0 # 周二 未打卡 0 (integer) 0 127.0.0.1:6379> setbit sign 2 0 # 周三 未打卡 0 (integer) 0 127.0.0.1:6379> setbit sign 3 1 # 周四 打卡 1 (integer) 0 127.0.0.1:6379> setbit sign 4 1 # 周五 打卡 1 (integer) 0 127.0.0.1:6379> setbit sign 5 0 # 周六 未打卡 0 (integer) 0 127.0.0.1:6379> setbit sign 6 1 # 周天 打卡 1 (integer) 0 # 查看某一天是否打卡 127.0.0.1:6379> getbit sign 0 (integer) 0 #周一 未打卡 0 127.0.0.1:6379> getbit sign 3 (integer) 1 #周四 打卡 1 127.0.0.1:6379> getbit sign 5 (integer) 0 #周六 未打卡 0 # 统计打卡天数 127.0.0.1:6379> bitcount sign (integer) 4 #四天打卡



