菜单 学习猿地 - LMONKEY

VIP

开通学习猿地VIP

尊享10项VIP特权 持续新增

知识通关挑战

打卡带练!告别无效练习

接私单赚外块

VIP优先接,累计金额超百万

学习猿地私房课免费学

大厂实战课仅对VIP开放

你的一对一导师

每月可免费咨询大牛30次

领取更多软件工程师实用特权

入驻
328
0

Redis 入门

原创
05/13 14:22
阅读数 87902

简介:Redis是Remote Dictionary Server的简写,由ANSI C语言编写,它是一种key-value形式的NoSql内存数据库,并提供多种语言的API;单线程架构,数据存放内存,故读写速度性能非常好;当然也支持内存中数据以快照和日志形式持久化到硬盘,从而在发生异常情况下数据也不会丢失。keyDB是从redis fork出来的分支,redis是一个单线程kv内存存储系统,而keyDB在兼容redis情况下,将redis改造为多线程。

一、特征

  1. Ehcache、Memcache和Redis的对比 

    A. Ehcache:直接在JVM中缓存,速度快且效率高,主要用于单体架构应用和对缓存访问要求很高的应用;

    B. Memcache:高性能,只支持key-value键值对,多线程、集群分布式的内存缓存系统;

    C. Redis:支持持久化、丰富的数据类型、单线程、集群分布式;

  2. 特点

    A. 性能高,速度快:读性能达到11w/s,写性能达到8.1w/s;

    B. 丰富的数据结构:如字符串、哈希、列表、集合、有序集合5种基础数据结构,还有位图(Bitmaps)、布隆过滤器(BloomFilter)、Hyperloglog、Geo复杂的数据结构;

    C. 丰富的特性:键过期实现定时缓存、发布订阅实现消息队列、事务功能、管道实现批量处理命令等;

    D. 丰富的客户端:主流的开发语言都接入了redis;

    E. 缺点会有缓存穿透、缓存雪崩、Redis和数据库双写一致性问题、Redis的并发竞争key问题等;

    F. list、hash、set的集合最大成员数为2的32次方-1即4294967295约42多亿。

  3. 应有场景

    A. 缓存:能够提升网站访问速度,大大降低数据库的压力;

    B. 排行榜:有序集合机构实现复杂排行;

    C. 计数器:用incr命令实现,适用于商品浏览量及视频播放量等;

    D. 分布式会话:集群模式下,用redis搭建session服务;

    E. 分布式锁:用setnx实现,适合并发访问高(全局ID、秒杀)的情况,Lua脚本保证多个命令一起执行,并发不高可用数据库悲观锁和乐观锁控制;

    F. 社交网络:用哈希或集合等数据结构实现,适合点赞等;

    G. 最新列表:lpush + ltrim来实现

    H. 消息系统:适合简单的消息队列,注意:不推荐使用,一致性等问题多

 

二、常用操作命令 

  1.  管理命令

    A. 启动:redis-server [--port 6379] | redis-server [../redis.conf]

    B. 连接:redis-cli -h 127.0.0.1 -p 6379 [-c]

    C. 停止:redis-cli shutdown | kill redis-pid

    D. 测试连通性:ping命令,返回PONG即连通

    E. 内存统计:info memory,info命令可以显示redis服务器的服务器基本信息、CPU、内存、持久化、客户端连接信息等

      used_memory:Redis分配器分配的内存总量(单位是字节),包括虚拟内存(swap);

      used_memory_rss:Redis进程占据操作系统的内存(单位是字节),即包括分配器分配的内存、进程运行本身需要的内存、内存碎片等,不包括虚拟内存;

      mem_fragmentation_ration:内存碎片比例,该值是used_memory_rss / used_memory的比值,一般大于1,值越大代表内存碎片比例越大,可以通过安全重启的方面来减小内存碎片,若小于1,代表redis开启了虚拟内存(磁盘),内存不足应增加内存或节点或优化应用等,对于jemalloc分配器来说,比例值为1.03左右是比较健康的状态;

      mem_allocator:Redis使用的内存分配器,有libc、jemalloc、tcmalloc,默认采用jemallocl,因为在控制内存碎片方面做得比较好。

  2. key命令(key都是字符串)

    A. keys patten:*是通配符,代表任意字符

      注意:keys是遍历算法,时间复杂度是O(n),加上Redis是单线程执行,即数据越多,时间越长,故上线后,不要使用keys *命令,避免服务器卡死;

         若要访问线上大数据量,则使用scan命令,虽然复杂度相同,但是不会阻塞线程。

    B. del key [key ...]:删除键,可以同时删除多个;

    C. type key:查询键类型;

    D. expire key seconds:设置过期时间,秒级别;注意:如果用DEL, SET, GETSET会将key对应存储的值替换成新的,命令也会清除掉超时时间,那么意味着set更新值,就必须重新设置expire,而对于list结构中添加一个数据或者改变hset数据的一个字段是不会清除超时时间的;

    E. ttl key:查询key的生命周期,秒级别,-1代表永不过期;

    F. exists key [key ...]:查询键是否存在;

    G. persist key:设置键永不过期;

  3. string命令(缓存、限流、计数器、分布式锁、分布式session等)

    A. set key value:存放键值;

    B. get key:获取键值;

    C. mset key value [key1 value1 ..]:批量存放键值;

       D. mget key [key1 ...]:批量获取键值。

  4. set命令(抽奖、赞、踩、标签、好友关系等):集合是无序且不可重复的,通过hash表实现的

    A. sadd key member1 [member2]:向集合添加一个或多个成员;

    B. scard key:获取集合的成员数;

    C. srem key member1 [member2]:移除集合中一个或多个成员;

    D. smembers key:返回集合中所有成员。

  5. zset命令(排行榜等):有序集合是散列表和跳跃表实现的,读取中间的元素较快,比列表占内存

  6.  list命令(微博关注人时间轴列表、简单队列等):列表是有序且可重复的,使用双向链表实现,两头快,中间慢

    A. lpush key value1 [value2]:将一个或多个值插入到列表头部(左边);

    B. rpop key:移除并获取列表的尾部(右边)的一个元素;

    C. rpush key value1 [value2]:将一个或多个值插入到列表尾部(右边);

    D. lpop key:移除并获取列表头部(左边)的一个元素;

    E. llen key:获取列表长度。

  7. hash命令(存储用户信息、用户主页访问量、组合查询等):适用于存储对象,是一个string类型的field和value的映射表

    A. hset key field value:将hash表key中的字段field的值设为value;

    B. hget key field:获取存储在hash表中指定字段的值;

    C. hdel key field1 [field2]:删除一个或多个hash表字段;

    D. hlen key:获取hash表中字段的数量。

 

三、key过期策略

  1. 作用:清理Redis中缓存的过期key,注意key到期后,redis并不是立即将过期的key删除;

  2. 策略分类

    A. 定时删除:每个设置过期时间的key都需要创建一个定时器,到过期时间就会立即清除,该策略可以立即清除过期的数据,对内存很友好,但是会占用大量的CPU资源去处理过期的数据,从而影响缓存的响应时间和吞吐量;

    B. 惰性删除:当你访问某个key的时候,Redis才会先检查是否过期,如果过期了就将对应的key删除,该策略可以最大化地节省CPU资源,却对内存非常不友好,极端情况可能出现大量的过期key没有再次被访问,从而不会被清除,占用大量内存;

    C. 定期删除:默认每1000ms随机获取设置了过期时间的部分key,如果已经过期就将对应的key删除,该策略是前两者的一个折中方案,通过调整定时扫描的时间间隔和每次扫描的限定耗时,可以在不同情况下使得CPU和内存资源达到最优的平衡效果;

    注意:Redis同时采用了定期删除+惰性删除两种策略。

 

四、内存淘汰机制

  1. 作用:当Redis最大内存大小不足以容纳新写入数据时,就会执行内存淘汰机制;

  2. 内存大小查看/修改

    A. redis.conf配置文件:

     B. 命令行:config get maxmemory / config set maxmemory 2gb;

  3. 淘汰策略分类

    不淘汰:

      A. noeviction(默认策略):对于写操作不再提供服务,直接返回错误(DEL请求和部分特殊请求除外);

    对设置了过期时间的数据进行淘汰:

      B. volatile-lru:在设置了过期时间的键空间中,移除最近最少使用的key;

      C. volatile-random:在设置了过期时间的键空间中,随机移除某个key;

      D. volatile-ttl:在设置了过期时间的键空间中,越早过期的key越优先被淘汰;

      E. volatile-lfu(Redis 4.0):在设置了过期时间的键空间中,使用LFU算法淘汰key;

    对所有数据淘汰:

      F. allkeys-lru:在所有键空间中,移除最近最少使用的key;

      G. allkeys-random:在所有键空间中,随机移除某个key;

      H. allkeys-lfu(Redis 4.0):在所有键空间中,使用LFU算法淘汰数据;

  4. 淘汰策略查看/修改

    A.  redis.conf配置文件:

       B. 命令行:config get maxmemory-policy / config set maxmemory-policy volatile-lru;

  5. LRU算法

    A. 定义:LRU(Least Recently Used),指如果一个数据在最近一段时间没有被用到,那么将来被使用到的可能性也很小,所以就可以被淘汰掉;

    B. Redis中LRU:Redis使用的是近似LRU算法,是通过随机采样法淘汰数据,每次随机取出默认值5个key,从里面淘汰掉最近最少使用的key,可以设置采集数:maxmemory-samples 10;

    C. 另外Redis 3.0对近似LRU算法做了优化;

  6. LFU算法

    A. 定义:LFU(Least Frequently Used),指根据key的最近被访问的频率进行淘汰,很少被访问的优先被淘汰,被访问的多的则被留下来;

    B. 优点:LFU算法能更好的表示一个key被访问的热度,因为基于访问频率衡量的,对于LRU算法,一个key很久没有被访问到,只刚刚是偶尔被访问了一次,那么它就被认为是热点数据,不会被淘汰,而有些key将来是很有可能被访问到的则被淘汰了。

 

五、持久化

  1. 方式

    A. RDB内存快照:RDB全称是Redis Database Backup,指在指定的时间间隔内将内存中的数据集快照写入磁盘,实际操作过程是fork一个子进程,先将数据集写入临时文件,写入成功后,再替换之前的文件,用二进制压缩存储;

    B. AOF日志文件(默认关闭):AOF全称是Append Only File,指以日志的形式记录服务器所处理的每一个写、删除操作,查询操作不会记录,以文本的方式记录,可以打开文件看到详细的操作记录。

  2. RDB

    A. 触发方式

      分手动触发:通过bgsave命令生成RDB文件;

      自动触发:save <seconds> <changes>,当满足一定时间值和一定数量写操作的情况下,Redis会将数据存储到硬盘;

    B. 配置项

    C. 优点

      当实例宕机恢复时,加载RDB文件的速度很快,能够在很短时间内迅速恢复文件中的数据;

      RDB文件数据是被压缩写入的,因此RDB文件的体积要比整个实例内存要小;

    D. 缺点

      由于是某一时刻的数据快照,故可能会发生数据丢失;

      生成RDB文件的代价是比较大的,它会消耗大量的CPU和内存资源;

    E. 应用场景

      主从全量同步数据;

      数据库备份;

      对于丢失数据不敏感的业务场景,实例宕机后快速恢复数据;

  3. AOF

    A. 配置项

    B. AOF重写:可以设置在AOF文件很大时,自动触发AOF重写,Redis会扫描整个实例的数据,重新生成一个AOF文件达成瘦身的效果;

    C. 优点

      数据文件更新比较及时,保存数据完整性强,降低丢失数据的风险;

      注意:如果同时存在RDB文件和AOF文件,Redis在服务器启动时会优先使用AOF文件进行数据恢复,因为数据完整。

    D. 缺点

      随着时间增长,AOF文件会越来越大;

      AOF文件刷盘会增加磁盘IO的负担,可能影响Redis的性能(开启每秒刷盘时);

    E. 应用场景:涉及金钱交易的业务。

 

  可参考:Redis持久化

 

六、事务

  1. 定义:事务执行过程将一系列多个命令按照顺序一次性执行,并且在执行期间,事务不会被中断,也不会去执行客户端的其他请求,直到所有命令执行完毕;

  2. 命令

    A. MULTI

    B. EXEC

    C. WATCH

  3. 工作原理

    A. 服务端收到客户端请求,事务以MULTI开始;

    B. 如果客户端正处于事务状态,则会把事务放入队列同时返回给客户端QUEUED,反之则直接执行这个命令;

    C. 当收到客户端EXEC命令时,WATCH命令监视整个事务中的key是否有被修改,如果有则返回空回复到客户端表示失败,否则redis会遍历整个事务队列,执行队列中保存的所有命令,最后返回结果给客户端,WATCH的机制本身是一个CAS的机制,被监视的key会被保存到一个链表中,如果某个key被修改,那么REDIS_DIRTY_CAS标志将会被打开,这时服务器会拒绝执行事务。

 

七、分区

  1. 定义:分区是分割数据到多个redis实例的处理过程,因此每个实例只保存key的一个子集;

  2. 分区意义:处理高并发和占用内存大问题,Redis集群就是分区的一种体现

  3. 分类

    A. 范围分区:分配一定范围的对象到特定的Redis实例;

    B. 哈希分区:利用hash函数将key转化为数字,哈希分区规则又包括节点区域分区、一致性哈希分区、虚拟槽分区;

 

可参考:Redis中方官网

发表评论

0/200
328 点赞
0 评论
收藏