Redis学习

发布时间:2023年12月29日

Redis在Window下使用简单,但是它推荐Linux去开发使用。

Redistribution配置文件:redis.conf。

Redis默认不是后台启动的,需要修改配置文件。

官方自带性能测试工具:redis-benchmark。

Redis基本知识

redis默认有16个数据库,使用使用第0个数据库。(select用于切换数据库,dbsize查看数据库大小,flushdb清空当前数据库,flushall清除所有数据库)

redis是单线程的。

set key value设置key和value
get key获得key的值
keys *查看所有key
set key valueset key
exists key判断当前key是否存在
move key db_num移除数据库下的key
expire key time设置key过期时间(秒)
ttl key查看当前key剩余时间
append key "string"最佳字符串,如果key不存在,就相当于set
incr key自增1
decr key自减1
incrby key num设置步长增加
decrby key num设置步长减少
getrange key start end获取子字符串
setex设置过期时间
setnx不存在再设置(在分布式锁中常常使用)
mset k1 v1 k2 v2 k3 v3.....批量设置
met k1 k2 k3 k4.....批量获取
set user:1 {key:value,key:value}设置对象
getset k1 v2先get再set
List操作
rpush将一个或多个值,插入到列表尾部(右)
lpush将一个或多个值,插入到列表头部(左)
lrange获取list值
lpop移除list第一个元素
rpop移除list最后一个元素
lindex list index通过下标获取list中的值
lrem list num value移除list集合中指定个数的value
ltrim list start end截取指定的长度
rpoplpush移除列表最后一个元素,将他移动到新的列表中。
linsert将某个value插入到列表中某个值大的前面或者后面
Set操作
saddset集合中添加值
sismember判断值是不是再set集合中?
scard获取set集合中的个数
srem删除set元素
srandmember随机从set中抽取元素
spop??随机删除set中的元素
smove将一个指定的值移动到另一个set集合中
sdiffset差集
sinterset交集
sunionset并集
Hash Map操作
hsetset一个具体的key-value
hmsetset多个具体的key-value
hget获取一个字段值
hmget获取多个字段值
hgetall获取全部数据
hdel删除hash指定的key字段
hlen??获取hash表的字段数量
hexists判断hash中字段是否存在
hkeys只获取所有fields
hvals只获取所有keys
incrby指定增量
decrby指定减量
hsetnx如果存在,则不能设置
Zset有序集合
zaddzset添加一个或多个有序值(add myset 1 one)
zrange查看zast
zrangebyscore通过score排序, -inf 负无穷? +inf 正无穷
zrem移除zset中元素
zcard获取有序集合中的个数
zrevrange从大到小排序!
zcount获取区间范围内set数量
geospatial地理位置
geoaddgeoadd city 116.40 39.90 beijin,增加一个或多个经纬度城市
geodist返回两地之间的距离
geohash返回11个字符的字符串,代表经纬度(将二维的字符串转换为一纬的字符串)
geopos获取指定地理位置
georadius以给定的经纬度为中心,找出某一半径的元素
georadiusbymember以给定的城市为中心,找出某一半径的元素
Hyperloglog(基数不重复,占用内存少)
PFadd添加
PFCOUNT统计基数数量
pfmerge合并
Bitmaps
setbit设置
getbit获取??
bitcount统计位数为1的个数

事务?

Redis单条命令是原子性的,但是事务不保证原子性。

所有的命令在食物中没用被直接执行,只有发起执行命令的时候才会被执行!Exec

开启事务multi
命令入队
执行事务exec
放弃事务discard

编译型异常(命令使用错误):事务中的所有命令都不会被执行。

运行时异常(1/0):其他命令正常执行,错误命令抛出异常。

监控

悲观锁:很悲观,认为什么时候都会出问题,无论做什么都会加锁。

乐观锁:很乐观,认为什么时候都不会出问题,所以不会加锁。

watch监听
unwatch取消监听

Jedis

Jedis是Redis官方推荐使用的java连接工具。使用Java操作Redis中间件。

  <!-- https://mvnrepository.com/artifact/redis.clients/jedis -->
        <dependency>
            <groupId>redis.clients</groupId>
            <artifactId>jedis</artifactId>
            <version>5.1.0</version>
        </dependency>

        <!-- https://mvnrepository.com/artifact/com.alibaba.fastjson2/fastjson2 -->
        <dependency>
            <groupId>com.alibaba.fastjson2</groupId>
            <artifactId>fastjson2</artifactId>
            <version>2.0.43</version>
        </dependency>
public class Main {
    public static void main(String[] args) {
        //1.new Jedis对象
        Jedis jedis = new Jedis("127.0.0.1",6379);
        //jedis所有的命令就是我们之前学习的所有指令
        System.out.println(jedis.ping());

    }
}

Springboot整合

jedis:采用的是直连,多个线程操作的话,是不安全的,如果想要避免不安全的话,使用jedis pool连接池。(BIO)

lettuce:采用netty,实例可以在多个线程中进行共享,不存在线程不安全的情况!(NIO)

Redis持久化

Redis是内存数据库,如果不讲内存中的数据库状态保存到磁盘中,那么一旦服务器进程退出,服务器的数据库状态也会消失。

RDB(Redis DataBase)

redis会单独创建(fork)一个子进程进行持久化,会先将数据写入一个临时文件中缓缓,代持就hi过程都结束了,再用这个临时文件替换上次持久化好的文件。整个过程主进程都不进行任何IO操作,这就确保了极高的性能。如果需要进行大规模数据的恢复,且对数据恢复的完整性不是很敏感,那EDB要比AOP更加高效。RDB的缺点就是最后一次持久化的数据可能会丢失。我们默认的就是RDB,一般情况下不需要修改。

rdb保存的文件是dump.rdb

触发机制:1.save规则满足的情况下? 2.执行flushall命令? 3.退出redis,也会产生rdb

AOP(Append Only File)

以日志的形式记录每个写操作,将Redis执行过的指令记录下来(读操作不记录)。只允许追加文件但不允许改写文件,redis启动之初会读取文件重新构建数据。换句话说,redis重启的话就根据日志文件的内容将写指令从前到后执行一次以完成数据的恢复工作。

默认不开启的,需要手动进行配置!我们只需要将appendonly改为yes就开启了aof。

如果aof文件有错误,redis会报错,需要修复这个文件。(使用redis-check-aof进行修复)。

相对于数据文件,aof远远大于rdb,修复的速度也比rdb慢。

主从复制

主从复制是指一台Redis服务器的数据复制到其他Redis服务器。前者称为主节点,后者成为从节点。数据的复制是单向的,只能由主节点到从节点。主节点以写为主,从节点以读为主。

哨兵模式

当主服务器宕机时,需要手动把一台从服务器切换为主服务器,需要人工干预,所以更多时候我们会使用哨兵模式(自动)。

哨兵模式能够后台监控主机是否故障,如果故障了根据投票数自动将从库转化为主库。

原理:Redis提供了哨兵的命令,哨兵是一个独立的进程,他会独立运行。其原理是哨兵通过发送命令,等待Redis响应,从而监控运行的多个Redis实例。然而一个哨兵进程可能会出现问题,为此我们可以使用多个哨兵进行监控。哨兵之间也会进行监控,这样就形成了多哨兵模式。

配置哨兵配置文件sentinel.conf

sentinel monitor myredis 127.0.0.1 6379 1

Redis缓存穿透和雪崩

缓存穿透:用户想要查询一个用户时,发现redis内存数据库没有,说明缓存没有命中,需要向持久层数据库查询,会对持久层数据库造成很大的压力,这就相当于缓存穿透。

缓存击穿:指一个key非常热点,在不断的扛着大并发,大并发集中对着一个点进行访问,当这个key在失效的瞬间(缓存过期),持续的大并发就穿破缓存,请求数据库,就相当于在屏障上凿开了一个洞。

缓存雪崩:在某一时间段,缓存集体过期失效,那么对数据的访问查询都会落到数据库上,造成了周期性的压力波峰,会造成存储村会挂掉。

文章来源:https://blog.csdn.net/m0_56159313/article/details/135197282
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。