redis必会基础命令、数据结构、lua脚本和分布式锁等

一次获取多个key的值

mget key1 key2

追加内容到指定key的值后面

append key1 xxx

获取值的长度

strlen key1

只有在key不存在时才成功

setnx key1 value1

只有在所有key不存在时才成功

msetnx key1 value1 key2 value2 …

给指定key的值加1

incr key1

减1

decr key1

给指定key的值加指定数值,本例是加2

incrby key1 2

给指定key的值减指定数值,本例是减2

decrby key1 2

获取指定key的值中指定范围的字符,如值为abcdefg,取1至2返回bc,即包含1和2两个位置的字符

getrange key1 1 2

设置指定位置的值,指定开始位置,然后直接覆盖,如下例中值为abcdefg,从第1个位置开始覆盖为cb,则结果为acbdefg

setrange key1 1 cb

复制代码

list

双向链表,无序可重复的集合,一般用来做队列

命令

从表头添加元素,value2是新的表头

lpush key1 value1 value2 …

从表尾添加元素,value2是新的表尾

rpush key1 value1 value2 …

从表头弹出元素

lpop key1

从表尾弹出元素

rpop key1

从key1表尾弹出一个元素,再加到key2表头

rpoplpush key1 key2

从表中查看指定索引的范围的元素

lrange key1 0 2

查看整个链表

lrange key1 1 0 -1

获取链表中从左向右指定索引的元素

lindex key1 1

获取链表中最后一个元素

lindex key1 -1

获取链表长度

llen key1

向链表中的value1前面插入value2

linsert key1 before value1 value2

向链表中value1后面插入value2

linsert key1 after value1 value2

从链表中删除一个值为value1的元素,从左向右

lrem key1 1 value1

从链表中删除一个值为value1的元素,从右向左

lrem key1 -1 value1

删除链表中所有值为value1的元素

lrem key1 0 value1

复制代码

set

无序不可重复的集合,常用来排除重复数据和随机抽奖功能

命令

向集合中添加元素,重复元素会自动跳过

sadd key1 value1 value2 …

取出集合所有元素

smembers key1

判断集合中是否存在某个元素

sismember key1 value1

获取集合中的元素个数

scard key1

从集合中删除指定元素

srem key1 value1 value2 …

随机从集合中弹出一个元素并删除该元素

spop key1

随机从集合中取出元素,但不会删除元素,后面的1表示取出元素的个数

srandmember key1 1

求两个集合交集

sinter key1 key2

求两个集合并集

sunion key1 key2

求两个集合差集

sdiff key1 key2

复制代码

zset

有序不可重复的集合,常用来做排行榜

命令

添加元素,相同value不同score会覆盖score

zadd key1 score1 value1 score2 value2

获取元素数量

zcard key1

取出全部元素,从小到大

zrange key1 0 -1

取出部分元素,从小到大

zrange key1 0 4

取出全部元素,从大到小

zrevrange key1 0 -1

取出部分元素,从大到小

zrevrange key1 0 4

取出score在指定范围内的元素,从小到大,其中min和max是score的范围

zrangebyscore key1 min max withscores

取出score在指定范围内的元素,从大到小

zrevrangebyscore key1 max min withscores

为指定value的元素的score递增,其中1是每次递增多少,可以为负数

zincrby key1 1 value1

删除指定元素

zrem key1 value1

统计集合中score在范围内的元素个数

zcount key1 min max

返回指定值在集合中的排名,从小到大,排名从0开始

zrank key1 value1

返回指定值在集合中的排名,从大到小

zrevrank key1 value1

复制代码

hash

类似于Java中的Map<String, String>

命令

添加一个键值对

hset key1 field1 value1

获取键值

hget key1 field1

批量设置键值对

hmset key1 field1 value1 field2 value2 …

检查键是否存在

hexists key1 field1

获取所有键

hkeys key1

获取所有值

hvals key1

键值递增,后面的1表示每次递增多少,可以为负数,当是负数时表示递减

hincrby key1 field1 1

键不存在时成功

hsetnx key1 field1 value1

获取所有键值对,奇数为键,偶数为值

hgetall key1

复制代码

bitmap

bitmap以bit为单位设置各个位的值(要么是0,要么是1),根据实际应用场景可以设计出节省空间的算法,如布隆过滤器,本文以记录用户签到为例,假设用户ID为1,每年一个key,并且key=用户ID_年份,如1_2021

ID=1的用户在2021-01-01这一天签到,这一天是2021年第1天(也就是第0天),可以执行以下命令,保存签到记录

设置1_2021这个key的第0个bit值为1,以此表示第0天签到成功

setbit 1_2021 0 1

复制代码

该用户在2021-01-03这一天签到,则执行以下命令

设置1_2021这个key的第2个bit值为1,以此表示第2天签到成功

setbit 1_2021 2 1

复制代码

现在想查询该用户在2021年的签到情况,可通过get命令实现

get 1_2021

输出\xa0

复制代码

get命令输出0xa0,这是十六进制,转成二进制,就是10100000,二进制中为1的位就表示那一天签到了,所以第0天和第2天签到了

判断该用户2021-01-03是否签到

getbit 1_2021 2

复制代码

统计该用户2021年有多少次签到,实际上是统计有多个位是1

bitcount 1_2021

输出2

复制代码

统计该用户指定日期范围内的签到次数,这个不太好实现,redis提供的命令中指定范围的单位是byte,比如统计2021年1月的次数,就是第0个字节到第3个字节(第0 1 2 3共4个字节),这样多统计了1天,即把2021-02-01这一天也统计进来,如下:

统计第0到第3个字节中为1的位个数,包含第3个字节

bitcount 1_2021 0 3

复制代码

这种情况要么按月来设定key值,要么单独查询2021-02-01这一天是否签到,如果签到则总次数就减1

通过上面的例子,可以看到以bit为单位存储非常节省空间,用8个bit就可以表示8天内的签到情况。也可以用bitmap来存储所有用户一天内的签到情况,这种就以用户ID作为bit的偏移量,如果用户ID很大,超过了bitmap的最大范围,可以通过用户ID分片到不同的bitmap上

地理位置

在同一个key内添加多个位置(经纬度),计算位置各个位置之间的距离,也可指定圆心按半径查找符合条件的位置,可实现附近的xxx功能

命令

向key1添加一个叫company的位置,经纬度为116.404844 39.915378

geoadd key1 116.404844 39.915378 company

向key1添加一个叫home的位置,经纬度为116.370924 39.930871

geoadd key1 116.370924 39.930871 home

查询指定位置的经纬度

geopos key1 company

查询多个位置的经纬度

geopos key1 company home

计算两个位置的距离,单位是m

geodist key1 company home

计算两个位置的距离,指定单位为km

geodist key1 company home km

以指定经纬度为圆心,查询指定半径内的所有位置,其中116.370924 39.930871是圆心点的经纬度,2000 m是半径大小,单位m,withdist表示输出符合条件的位置与圆心的距离,withcoord表示输出符合条件的位置的经纬度,asc表示按距离从小到大排序

georadius key1 116.370924 39.930871 2000 m withdist withcoord asc

以指定位置为圆心,查询指定半径内的所有位置,返回结果中包含圆心自身,其他可选参数与上一条georadius相同

georadiusbymember key1 home 4000 m

复制代码

持久化

redis大部分时间用来做缓存,通常数据丢失也可以恢复,但是有时候也会用来存储热门的数据,或者nginx直接连接redis做一些重要数据的存储(丢失后很难恢复),所以redis中的数据需要持久化

redis提供了RDB和AOF两种持久化方式,RDB是对当前数据的全量备份(理解成快照),AOF采用追加的方式记录所有写入的命令,所以一般AOF文件更大,可能导致硬盘被占满,这一点需要注意,需要及时的对AOF文件进行瘦身

RDB

执行savebgsave命令会生成一份当前内存数据的快照到.rdb文件内,其中bgsave命令是另起一个线程去执行,因此不会阻塞主线程

redis默认开启了RDB,redis会自动进行RDB存储,RDB常用配置参数:

save 300 1000 # 每隔300秒,如果有1000个key发生了变化,则备份一次

save 30 10000 # 每隔30秒,如果有10000个key发生了变化,则备份一次

复制代码

上面的参数不能乱改,要根据redis的写入数据情况来设置,不能太频繁的生成RDB快照,这会影响redis的性能

AOF

一般做持久化要同时开启RDB和AOF,下面介绍工作中如何设置redis的AOF,编辑redis.conf配置文件,修改以下配置项

开启AOF

appendonly yes

AOF文件名

appendfilename “xxx.aof”

将命令刷入磁盘的间隔,everysec是每秒一次

appendfsync everysec

在执行bgrewrite的时候不向磁盘刷新数据

no-appendfsync-on-rewrite no

复制代码

关于appendfsync的意思:在计算机组成原理中,我们知道相对于内存而言对磁盘的读写是很慢的,所以CPU将数据写入内存缓冲区,定时或存满后再写入磁盘,redis的AOF中appendfsync这个配置就是设置多久写入磁盘一次,设为一秒是比较保险的,如果发生故障只会丢失最近1秒内的数据

RDB和AOF对比

  1. RDB定期对内存中的数据进行快照,会影响redis的性能,所以不能太频繁

  2. RDB在快照之间如何发生错误会丢失此段时间内的数据

  3. RDB在重启redis时恢复速度更快,不像AOF那样需要一条一条命令执行

  4. AOF可设置每秒追加一次写入命令到aof文件中,所以发生故障时丢失数据最少

  5. AOF文件中保存的是redis的写入命令,所以可以打开文件进行修改,删除不需要的命令

  6. AOF的缺点是要记录redis做的每一步写入命令,所以文件很大,需要及时进行瘦身

lua脚本

介绍

redis中默认就支持lua脚本,我们通常会使用lua脚本来代替redis事务,可解决超卖和少卖的情况

以下是redis的lua脚本特性:

  1. 原子操作,lua脚本会作为一个整体执行,不会被其他连接的命令中断,因此可替代事务

  2. lua脚本加载后可重复使用

  3. 减少网络请求的开销,一次性发出一个lua脚本到redis,redis执行完后返回结果,不用多次请求

用法

直接执行

eval 脚本 参数数量 参数名1 参数名2 值1 值2

复制代码

示例:

eval “return KEYS[1]…ARGV[1]” 1 key1 val1

输出

key1val1

复制代码

lua脚本中KEYSARGV两个数组名是固定的,且索引从1开始,上面例子中参数数量为1,参数名1为key1,值1为val1,而脚本是拼接key1和val1,所以结果就是key1val1了

注意:如果脚本有多个参数,则参数名写在一起,参数值写在一起,如key1 key2 val1 val2,而不是key1 val1 key2 val2

加载脚本

加载脚本的目的是重复使用,通过script load命令实现,返回一个sha1的hash值,之后通过此值可调用已加载的脚本

script load “return KEYS[1]…ARGV[1]”

假设返回3783a90bf1f43b15a1e06c4e7664da956ed959d9

复制代码

调用脚本

自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。

深知大多数Java工程师,想要提升技能,往往是自己摸索成长或者是报班学习,但对于培训机构动则几千的学费,着实压力不小。自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!

因此收集整理了一份《2024年Java开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。img

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Java开发知识点,真正体系化!

由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且会持续更新!

如果你觉得这些内容对你有帮助,可以扫码获取!!(备注Java获取)

img

最后

面试是跳槽涨薪最直接有效的方式,马上金九银十来了,各位做好面试造飞机,工作拧螺丝的准备了吗?

掌握了这些知识点,面试时在候选人中又可以夺目不少,暴击9999点。机会都是留给有准备的人,只有充足的准备,才可能让自己可以在候选人中脱颖而出。

《一线大厂Java面试题解析+核心总结学习笔记+最新讲解视频+实战项目源码》点击传送门即可获取!
2024年Java开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。**[外链图片转存中…(img-5NylxLic-1712058406633)]

[外链图片转存中…(img-99zVBrf2-1712058406633)]

[外链图片转存中…(img-RtTBaYgg-1712058406634)]

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Java开发知识点,真正体系化!

由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且会持续更新!

如果你觉得这些内容对你有帮助,可以扫码获取!!(备注Java获取)

img

最后

面试是跳槽涨薪最直接有效的方式,马上金九银十来了,各位做好面试造飞机,工作拧螺丝的准备了吗?

掌握了这些知识点,面试时在候选人中又可以夺目不少,暴击9999点。机会都是留给有准备的人,只有充足的准备,才可能让自己可以在候选人中脱颖而出。

[外链图片转存中…(img-w3WEvOgO-1712058406634)]

[外链图片转存中…(img-YLGt3taZ-1712058406635)]

《一线大厂Java面试题解析+核心总结学习笔记+最新讲解视频+实战项目源码》点击传送门即可获取!

  • 5
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值