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)。
# 查看所有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
# 清空全部数据库
flushall
###############################################################
# 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的头部(左)
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小结:
# 往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 set2
# 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 hello
# 添加一个/多个值,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,可以通过官网的官方文档查看
朋友定位、附近的人、打车距离计算
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:
两人之间的距离
单位:
# 获取两地的距离,后面是单位
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
......
什么是基数?
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) 11
位存储
#七天打卡
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 #四天打卡