redis 总结

  • 事务

  • ACID原子性、一致性、隔离性和持久性。

  • redis事务中任意命令执行失败,其余命令依然执行。它不保证事务的原子性,也不支持回滚。事务中的多条命令一次性发给服务器,服务器在执行事务的过程中不会执行其它客户端的命令请求。它做到了隔离性,原子性无法保证。

  • redis数据持久化

  • rdb 全量持久化
    rdb 通过save或bgsave触发,然后父进程执行fork操作创建子进程(创建过程会阻塞);子进程创建 rdb文件,根据父进程内存(这个内存需要拷贝)生成临时快照文件;完成后对原有文件进行原子替换(定时一次性将所有数据进行快照生成一份副本存储在硬盘中)。
    优点:是一个紧凑压缩二进制文件,redis加载rdb恢复数据远快于aof方式。
    缺点:每次生成rdb开销大,非实时持久化。

  • aof 增量持久化
    aof 开启后,redis每执行一个修改数据的命令,都会把这个命令添加到aof文件中。查询不会写日志操作,修改和删除会写入日志操作。
    优点:
    1、实时持久化。
    2、可以设置不同的策略,如fsync 1s一次,这样最多丢失1s的数据,默认是1s一次,这种配置下,redis性能依然保持比较好。
    3、aof文件是一个只进行追加操作的日志文件(append only log),因为对aof文件的写入不需要进行seek。redis可以在aof文件体积变得过大时,自动地在后台对aof进行重写,重写后的aof文件包含了恢复当前数据集所需的最小命令集合。整个重写操作绝对安全,因为在redis创建aof文件的过程中,会继续将命令追加到现在的aof文件里面,即使重写过程中发生停机,现有的aof文件也不会丢失。而一旦新的aof文件创建完毕,redis就会从旧的aof文件切换到新的aof,并开始对新aof文件进行追加操作。
    缺点:
    1、由于aof文件体积逐渐变大,需要定期执行重写操作来降低文件体积,加载慢。
    2、对于相同的数据集,aof文件体积比rdb要大。
    3、根据所使用的fsync策略,aof的速度可能会低于rdb。关闭fsync策略可以让aof的速度和rdb一样快。

  • redis单线程为什么快

  • 单线程避免线程竞争,使用内存减少磁盘io,多路复用模型,用了缓冲区概念。

  • 虚拟内存
    当key很小,value很大时,使用vm的效果会比较好,因为节约的内存比较大。
    当key不小时,可以考虑使用一些方法,将很大的key变成很大的value,比如可以考虑将key,value组合成一个新的value。vm-max-threads可以设置访问swap文件的线程数,设置最好不要超过机器的核数,如果设置为0,那么所有对swap文件的操作都是串行的,可能会造成长时间的延迟,但对数据完整性有很好的保证。

  • 热点数据回收

    将db中的常用数据缓存至redis,6种回收策略

  • 1 volatile-lur:从已设置过期时间的数据集(server.db[i].expires)中挑选最近最少使用的数据淘汰。

  • 2 volatile-ttl:从已设置过期时间的数据集(server.db[i[].expires)中挑选将要过期的数据淘汰。

  • 3 volatile-random:从已设置过期时间的数据集(server.db[i].expires)任选选择数据淘汰。

  • 4 allkeys-lru:从数据集(server.db[i].dict)中挑选最近最少使用的数据淘汰。

  • 5 allkeys-ttl:从数据集中(server.db[i].dict)中任意选择数据淘汰。

  • 6 no-enviction(驱逐):禁止驱逐数据。永不回收。
    volatile表示从过期的数据集中,allkeys表示从所有的数据集中。
    使用策略规则:
    1、如果数据呈现幂等分布,就是一部分数据访问频率高,一部分访问频率低,则使用allkeys-lru。
    2、如果数据呈现平均分布,也就是所有数据的访问频率相同,则使用allkeys-random。
    ttl和random好理解,lru使用最近最少使用的策略,设计上会对key按失效时间排序,然后取最先失效的key进行淘汰。

  • 参考
    redis是单进程,单线程,它利用队列技术将并发访问变为串行访问,消除了传统数据库进行串行控制的开销。

  • 解决并发竞争

    redis采用队列模式,将并发访问变为串行访问。它本身没有锁的概念。redis对于多个客户端连接并不存在竞争,但是jedis客户端进行并发访问时会造成连接超时、数据转换错误、阻塞、客户端关闭等问题。这都会造成客户端混乱。
    解决并发竞争
    1.客户端角度,对连接进行池化,同时对客户端读写redis操作采用内部锁synchronized。
    2.服务器角度,利用setnx实现锁。

  • 事务cas(check-and-set)

    redis执行事务过程中,不会为其它客户端的请求提供任何服务。这样可以保证事务中的所有命令被原子的执行。
    redis事务中如果某一条命令执行失败,其后的命令仍然会被继续执行。
    multi exec discard watch
    如果中途机器崩溃,要看exec执行的时间点是在崩溃前或是在写入的过程中,断电前崩溃的话,会执行完事务。如果是在写入的过程中,也许会有部分的数据写入,部分的丢失。
    redis重启时会进行一些必要的一致性检测。redis-check-aof
    工具,可以帮我们定位到数据不一致的错误,并将已写入的部分数据进行回滚。

  • watch命令和基于cas的乐观锁

    redis事务中,watch命令可提供cas(check-and-set)功能。
    假如我们通过watch命令在事务执行之前监控了多个keys,倘若在watch之后有任何key的值发生了变化,exec命令执行的事务都将被放弃,同时返回null mlti-bulk应答来通知调用者事务执行失败。
    watch mykey
    val = get meykey
    val = val+1
    multi
    set mykey $val
    exec
    这段代码在获取mykey之前,进行监控,此后将set命令包围在事务中,这样就可以保证每个连接在执行exec之前,如果当前获取的mykey的值被其它连接的客户端修改,那么当前连接的exec命令将执行失败。这样调用者在判断返回值后就可以获悉val是否被重新设置成功。

  • 缓存失效策略和主键失效机制

    redis中,有生存期的key被称为volatile。在创建缓存时,要为给定的key设置生存期,当key过期时,生存期为0,可能会被删除。

  • 1.影响生存时间的操作
    del、set、getset来删除或覆盖原有数据。修改之后,生存时间会与之前不同。
    比如对一个key进行incr,列表lpush或哈希表执行hset命令,这类操作不会修改key的生存时间。如果rename一个key,改名后的key的生存时间和之前相同。
    rename命令的另一种可能是,尝试将一个带生存时间的key改名成另一个带生存时间的another_key,这时旧的another_key(以及它生存时间)会被删除,然后旧的key会改名为another_key,因此新的another_key的生存时间也和原来的key一样。使用persist命令可以在不删除key的情况下,移除key的生存时间,让key生新成为一个persistent key

  • 2.如何更新生存时间
    expire命令 时间复杂度o(1)
    expire ttl命令搭配使用,ttl可以查看key的当前生存时间,设置成功返回1;当key不存在或不可设置生存时间时返回0。
    最大缓存配置 server.maxmemory,如果为0,表示没有指定,如果有新数据添加超最大内存,会导致redis崩溃。所以一定要设置,当数据集上升到一定大小的时值,会实行数据淘汰策略。
    可视化工具有redis client以及redis desktop manager可以用下看看。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值