基础知识及基本命令
Redis默认有16个数据库
查看redis.conf
文件,可以看到有个 databases 16
的属性
默认使用的是第0个,可以使用 select 命令进行切换
dbsize
命令是查看大小
不同的数据库之间的内容不共享,比如把一个键值对放在了三号库里,在七号库是查不到的
查看当前库所有键值对的键
keys *
清空当前库的所有键值对
flushdb
清空所有数据库的键值对
flushall
Redis是单线程的!
Redis是很快的,官方表示,Redis是基于内存的操作,cpu不是Redis的性能瓶颈,Redis的瓶颈是根据机器的内存和网络带宽,既然可以使用单线程来实现,就使用单线程了!
Redis是C语言写的,官方提供的数据为100000+的QPS,完全不比同样使用 key-value 的 MemCache
差
误区1:高性能的服务器一定是多线程的
误区2:多线程(CPU发生上下文切换)一定比单线程效率高
核心:Redis是将所有的数据全都放在内存中的,所以使用单线程去操作的话,效率就是最高的。
五大基本数据类型
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)。
注意:操作成功返回1或OK,失败返回0
判断一个键值对是否存在,如果存在则返回1
exists 键
移除一个键值对
move 键
给一个键值对设定一个期限,到期后自动移除该键值对
expire 键 过期秒数
查看一个键对应的value数据类型
type 键
String
给一个键值对的值追加值,和其他的append用法差不多。返回值是追加后的字符串长度
append 键 追加的值
查看一个值的长度
strlen 键
自增1
incr 键
自减1
decr 键
设置自增或自减步长
incrby 键 步长
decrby 键 步长
截取字符串,字符串第一位下标为0。查看全部字符串的话,开始下标为0,结束下标为-1就好
getrange 键 开始位置下标 结束位置下标
替换字符串
setrange 键 开始位置 替换的值
设置值同时设置过期时间
setex 键 期限 值
如果不存在就设置值(在分布式锁中十分常用!)
setnx 键 值
批量设置值
mset 键1 值1 键2 值2
批量获取值
mget 键1 键2 键3
批量如果不存在就设置值(在分布式锁中十分常用!),注意!这里是原子性的操作,如果在批量设置时有一个键已存在,本次设置的都会失败
setnx 键1 值1 键2 值2
先获取再赋值,获取时获取的是之前的,然后进行设置。第二次使用时,获取的就是第一次设置的,然后替换掉获取到的
getset 键 值
对象
设置一个 user:1 对象,值为json字符串来保存对象属性值
set user:1 {username:mahe666,password:123456}
设置user对象,id为1,username为mahe666
set user:1:username mahe666
设置user对象,id为1,password为123456
set user:1:password 123456
批量设置user对象
mset user:1:username mahe666 user:2:password 123456
对象类型:主键:属性
List
在Redis里面,我们可以把List玩成栈、队列、阻塞队列
大部分的List命令都是以l(L的小写)开头的
向列表头部添加一个或多个值(左插入)
lpush 列表名 值
查询全部列表,列表第一位下标为0。查看列表全部值的话,开始下标为0,结束下标为-1就好
lrange 列表名 开始下标 结束下标
向列表尾部添加一个或多个值(右插入)
rpush 列表名 值
去掉列表最左边的值(头部)
lpop 列表名
去掉列表最右边的值(尾部)
rpop 列表名
从左侧按照下标查看列表中的单个元素
lindex 列表名 下标
查看列表的长度
llen 列表名
移除列表中的数据,注意!列表中可能会有多个相同元素,所以可以指定删除数量
lrem 列表名 删除数量 元素值
按照指定的长度截取列表,然后替换掉被截取的列表
ltrim 列表名 开始下标 结束下标
移出列表最后一个元素,然后将该元素添加到其他列表中
rpoplpush 列表名 目标列表名
替换列表中指定下标的元素
lset 列表名 下标 新元素
向列表中的一个元素前面后面新增一个元素
linsert 列表名 before/after 元素 要添加的元素
List其实是一个链表
在两边插入或改动值,效率最高!如果链表过长,在操作中间元素的时候,效率偏低
Set
Set是一个集合,但是里面存放的值不能重复
向Set集合中添加一个元素
sset 集合名 元素
查看一个Set集合中的所有元素
smembers 集合名
判断一个元素是否在一个Set集合中
sismembers 集合名 元素名
查看一个Set集合的元素数量
scard 集合名
移除Set集合中的元素
srem 集合名 元素名
随机选出Set集合中的元素
srandmember 集合名
随意移除Set集合中的一个元素
spop 集合名
将Set集合中的一个值移动到另外一个集合中
smove 原集合 目标集合 元素名
查看第一个Set集合和第二个Set集合的差集
sdiff 集合名1 集合名2
查看两个Set集合的交集 (两个人的共同好友就可以这样实现)
sinter 集合名1 集合名2
查看两个Set集合的并集
sunion 集合名1 集合名2
Hash
Hash(哈希散列,Map集合)
key-value(value在这里就是Map集合)
向map集合中添加一组键值对
hset map集合名 map键名 map元素
获取map集合中对应键的值
hget map集合名 map键名
同时向map集合中添加多组键值对
hmset map集合名 map键名1 map元素1 map键名1 map元素1
同时获取map集合中多个键对应的值
hmget map集合名 map键名1 map键名2
获取map集合中所有的键值对(单数是键,单数加1的双数为键对应的值)
hgetall map集合名
指定删除map集合中的一组键值对
hdel map集合名 键名
查看map集合中有多少组键值对
hlen map集合名
判断map集合中指定字段是否存在
hexists map集合名 键名
查看map集合中所有的键
hkeys map集合名
查看map集合中所有的值
hvals map集合名
使map集合中的一组键值对的值自增或自减
hincrby map集合名 键名 步长
hdecrby map集合名 键名 步长
如果map集合中对应的键不存在,则向map集合中添加键值对
hsetnx map集合名 键名 元素名
hash更适合于存储对象的存储,String更适合于字符串的存储
ZSet
ZSet(有序集合)
在Set的基础上加了一个序号的值
向ZSet集合中添加元素
zadd ZSet集合名 排名 元素
按照下标查看元素
zrange ZSet集合名 开始值 结束值
按照从小到大顺序查看元素,可以通过设置一个区间来查看范围内的值(-inf是负无穷,+inf是正无穷)
zrangebyscore ZSet集合名 最小值 最大值
按照从小到大的顺序查看元素及序号,可以通过设置一个区间来查看范围内的值(-inf是负无穷,+inf是正无穷),单数是元素,单数加一的双数是元素对应的序号
zrangebyscore ZSet集合名 最小值 最大值 withscores
移除ZSet集合中的元素
zrem ZSet集合名 元素名
按照从大到小的顺序查看元素,可以通过设置一个区间来查看范围内的值(+inf是正无穷,-inf是负无穷)
zrevrange ZSet集合名 最小值 最大值
zreverange ZSet集合名 0 -1
获取ZSet集合中指定区间的数量
zcount ZSet集合名 最小值 最大值
三大特殊数据类型
Geospatial 地理位置
这个功能可以推算地理位置的信息:两地之间的人,方圆几里的人
朋友定位,附近的人,打车距离计算!
相关文章:
有效的经度从-180度到180度。
有效的纬度从-85.05112878度到85.05112878度。
当坐标位置超出上述指定范围时,该命令将会返回一个错误。
常用的方式是父名称是国家,子名称是城市
添加地理位置
geoadd 父名称 经度 纬度 子名称
获取地理位置
geopos 父名称 子名称
查看两地之间的距离,单位:m表示为米,km表示为千米,mi表示为英里,ft表示为英尺
geodist 父名称 子名称1 子名称2 单位
以给定的经纬度为中心,找出某一半径内的元素
georadius 父名称(搜索范围) 经度 纬度 半径长度 单位
输出的时候同时输出两地距离
georadius 父名称(搜索范围) 经度 纬度 半径长度 单位 withdist
输出的时候同时输出查询结果的经纬度
georadius 父名称(搜索范围) 经度 纬度 半径长度 单位 withcoord
输出上面两个语句时限制输出个数
在语句后面加 count 数量
以已存在的元素为中心,找出某一半径内的元素
georadiusbymember 父名称(搜索范围) 元素名 半径长度 单位
返回一个或多个位置元素的geohash表示,将二维的经纬度转换为一维的字符串,如果两个字符串越接近,那么则距离越近
geohash 父名称 子名称1 子名称2
Geospatial的底层原理其实就是ZSet
可以看到上面没有删除地理位置的命令,所以想要删除掉地理位置信息,需要用到zrem命令
Hyperloglog 基数统计
比如现在有两个集合,这两个集合重复的元素是5个,那么基数就是5
优点:占用的内存是固定的,2^64 不同元素的技术,是需要占用12KB的内存!如果要从内存角度来比较的话, Hyperloglog
是首选
例:需要统计网站的UV(访问量,一个人访问多次也算作一次)
传统的方式,set集合保存用户的id,然后就可以统计set集合中的元素数量作为标准判断
这个方式如果保存大量的用户id,就会比较麻烦!我们的目的是计数,而不是保存用户id
0.81%错误率!统计UV任务,可以忽略不计
创建一组元素
pfadd 组名 元素名1 元素名2
按照键名输出组内元素数量
pfcount 组名
合并多组元素并创建一个新组
pfmerge 新组名 组名1 组名2
如果允许容错,使用Hyperloglog就好
如果不允许容错,就使用set集合或者自己想用的数据结构就好
Bitmap 位图场景
统计用户信息,活跃,不活跃;登录,未登录;打卡签到!只要是只有两个状态的就都可以使用Bitmap!
Bitmap位图,数据结构!都是操作二进制位来进行记录,只有0和1两个状态
如果需要统计365天内的打卡情况,就需要365bit,一个字节 = 8bit!差不多在46字节左右
初始化一个位图,参数必须大于或等于 0 ,小于 2^32,参数常用来打卡时标记第几天
setbit 位图名 参数 值
获取一个位图的参数对应的值
getbit 位图名 参数
输出位图中值为1的数量
bitcount 位图名
Redis事务
mysql的事务原子性:一组事务要么都成功,要么都失败
Redis可以正常保证单条命令原子性;但是Redis不能保证一组事务的原子性
Redis事务本质:一组命令的集合。比如:重复使用set命令插入数据,它会排队依次执行命令。这个时候是不允许被打断的,如果出错,则对单条数据执行处理错误的机制
一个事务中所有的命令都会被序列化,在事务的执行过程中,会按照顺序执行!一次性,顺序性,排他性的执行命令
Redis事务没有隔离级别的概念
所有的命令在事务中,并没有被直接执行;只有发起执行命令的命令时才会执行
执行命令的命令
exec
Redis的事务
- 开启事务( multi )
- 命令入队( 正常命令... )
- 执行事务( exec )
注意!每一次执行事务后,都需要再次开启事务
- 放弃事务( discard )
编译型异常(代码有问题!命令有错!),事务中所有的命令都不会被执行
运行时异常(运行时代码或命令报错),则错误代码不执行,其他命令继续执行
Redis乐观锁
mybatis-plus中使用了version字段实现了乐观锁
在Redis中使用watch关键字来实现这个功能
比如说要修改某一个键值对,就需要使用watch命令来监听他
watch 键名
然后开启事务进行提交
如果在监听键值对后且事务未提交前,监听的键值对发生改变,则会更新失败
解决办法是使用unwatch命令取消监听,重新使用watch命令监听
unwatch
然后再次提交数据