Redis

本文详细介绍了Redis的内存存储、数据类型、快速性能原理、缓存管理策略、持久化方法、高可用架构(主从、哨兵和集群)以及常见问题解答,包括多线程、事务和哈希冲突处理。
摘要由CSDN通过智能技术生成

2.2.1 概述

        Redis(Remote Dictionary Server)远程字典服务,是一个开源的、支持网络、可基于内存、亦可持久化的日志型,key-value数据库,并提供多种语言API,与MySQL不同的是,Redis数据存储在内存中,可支持10W次读写每秒,此外Redis支持事务、持久化、LUA脚本、LRU码区,多集群方案等。

2.2.2 Redis常用数据类型

        常用五种

        1. String(字符串)

                二进制安全,最大存储512M,String内部编码有三种,int、embstr(小于等于39字符字符串)、raw(大于39字符字符串)

                C语言的字符串基于char[] ,而Redis字符串使用SDS(Simple Dynamic String)封装

                        unsigned        int        len        标记buff长度

                        unsigned        int        free        buff中未使用元素长度

                        char buf[]        存放数据的坑

                SDS可以在时间复杂度O(1)获取字符串长度而char[]O(n)

        2. Hash(哈希)

                hash的value本身又是一个键值对结构,类似hashmap

                内部编码:ziplist(压缩表) hashtable(哈希表)

        3. List(列表)

                存储多个有序字符串,一个列表最多存储2e32-1个元素

                内部编码:zipList(压缩表) LinkedList(链表)

        4. Set(集合)

                多个元素,无序,不重复

                内部编码:intSet(整数集合) hashTable(哈希表)

        5.ZSet(有序结合)

                有序,不重复

                内部编码:ZipList(压缩表),sripList(跳跃表)链表+多级索引

        特殊三种

        1.Geo 地理信息

        2.HyperlogLog 基数统计算法的数据结构

        3. BitMaps 用一个bit位表示映射状态,理解为一个比特为单位的数组

2.2.3 Redis为什么快

        1. Redis基于内存

        2. 高效数据编码和编码结构

                数据结构:压缩表、SDS、哈希表、跳跃表

        3.合理的线程结构

                单线程+IO多路复用

        4. 虚拟内存机制

                冷热数据分离

2.2.4 缓存穿透、缓存雪崩、缓存击穿

        1.缓存穿透

                原因:查询大量不存在key,穿透缓存,直达数据库,造成数据库压力

                解决:a.设置参数校验,避免非法key传入

                           b.设置空值缓存,过期时间

                           c.bloomFilter,使用布隆过滤器判别数据是否存在,存在才去查

                BloomFilter

                            底层由二进制向量和随机映射函数组成,可高效查询一个key是否存在set中,类似集合的contain。

                             优点:时间复杂度低,不存储数据(安全),存储空间小。

                             缺点:存在一定误判率(误判,有->一定是true,没有->可能是true)。

                             实现:BloomFilter.create(Funnels.类型,预期数据量,误判率)

        2.缓存雪崩

                原因:大量key同时到期,访问数据库,造成数据量压力过大

                解决:设置离散过期时间

        3.缓存击穿

                原因:热点key过期,恰巧大量此热点key同时访问,直达数据库

                解决:a.热点key永不过期(异步线程更新过期时间)

                           b.设置互斥锁,缓存过期不直接访问db,通过Redis原子操作 setnx

2.2.5 Redis过期策略和内存淘汰策略

        1.过期策略

                a.定时过期:到期立即清除,内存友好,占用CPU资源

                b.惰性过期:到期不删除,下次访问时判断是否过期,过期则清楚,内存不友好,CPU友好

                c.定期过期:隔100ms随机抽取一定数据,进行检查是否过期,过期删除。其他数据采用惰性过期方式

        2. 内存淘汰(当Redis内存不足时)

                a. volate-lru LRU清除算法        清除        设置了过期时间的key

                b. allKeys-lru LRU清除算法      清除        所有key

                c. volate-lfu LUF清除算法         清除        设过期key

                d. allKeys-lfu LFU清除算法       清除        所有key

                e. volate-Random 随机             清除        设置了过期时间key

                f. allkeys-Random 随机             清除        所有key

                g. volate-ttl        越早过期        越先清除

                h. noeviction      默认、内存不足抛出异常

2.2.6 Redis持久化

        1.文件加载流程

                a.redis启动

                b.判断是否开启AOF?

             (1)是:是否存在AOF ?(1.1)是:加载AOF并判断是否加载成功 ?(1.1.1)成功

                                                                                                                                 (1.1.2)失败

                                                         (1.2)否:是否存在RDB?(1.2.1)否   启动完成

                                                                                                       (1.2.2)是:加载RDB   (1.2.2.1)成功

 (1.2.2.2)失败

             (2)否:是否存在RDB   (2.1)否   启动完成

                                                       (2.2)是:加载RDB    (2.2.1)成功

                                                                                              (2.2.2)失败

                即,先判别AOF,再判别RDB

        2.AOF        

                以日志方式记录Redis每个操作,默认不开启

                优点:一致性,完整性

                缺点:文件大,恢复慢

        3.RDB

                redis默认方式,将快照保存到磁盘,redis安装目录下自动生产dump.rdb文件

                触发方式:a. 手动        save同步、bgsave异步

                                  b. 自动        在m秒内执行n次操作,触发RDB自动写入

                优点:适合大规模数据,集群化场景

                确定:不能实时

2.2.7 Redis高可用(分布式)

        1. 主从模式

                主节点负责读写,从节点只读,主从复制机制由全量复制和增量复制实现

                        a. 全量复制(从节点第一次连接主节点时)

                                        master                                                    slave

                                缓存RDB生产期间写命令      RDB->           载入快照

                                缓存RDB同步期间写命令     同步缓存->      执行缓存命令   

                         b. 增量复制

                                通过replicationFeeddSlaves()函数,同步有数据更新的主节点redis操作

        2. 哨兵模型

                监控主节点,若主节点下线,从节点升级为主节点

                故障切换过程:主节点宕机,哨兵1检测到,不会直接failover,当检测到此情况哨兵到一定数量,发起投票,执行failover,切换成功后通过发布订阅模式,通知从节点切换master

        3. 集群模式

                为避免每个节点存储相同数据造成浪费,Redis3.0加入分布式存储,对数据进行切片,每台节点存储不同内容,来解决在线扩容问题,且可以解决复制和故障转移问题。

                节点间通过Gossip协议进行通信,常用Gossip消息如下:meet、ping、pong、fail

                Cluster集群分布算法是Hash Slot插槽算法,也叫哈希槽算法,通过哈希映射CRC16算法计算出一个16位的值,对16384取模,放到数据库的16384个哈希槽中。

                其中,高可用还是由主从实现,主管下线:某个节点人为另一个节点不可以。客观下线:多个节点共识结果。

        集群部署

                a.redis集群需要六个节点,三主三从

                b.通过GCC(编译器)  make 编译、安装 Redis

                c. 分发安装好的Redis到每个节点,并改写Redis.conf文件,每个节点独立的ip,端口,和总线端口。

                d.关闭防火墙

                e.开启每个节点redis服务器        ./bin/redis-server        redis.conf

                f.开启集群

                        redis下载解压后的包->src

                        ./redis-cli --cluster create ip:port ......  --cluster replicates1

                g. 加入节点

                        客户端登录         redis/bin 目录下, ./reis-cli -h ip -p port

                                                    CLUSTER MEET ip port

                h.redis集群创建完成,进入任意客户端,即可访问

        IDE连接集群Redis    

                a. 开启集群,导入Jedis jar包

                b. 创建集群信息set

                        set.add(new HostAndPort("IP","port"));

                        new JedisCluster(set);

                c.通过JedisCluster   set get方法        存、取

                d.关闭        JedisCluster.close()

2.2.8 常见问题

        1.redis多线程

                redis在处理客户端请求时,如socket解析,执行,都是单线程,只有在网络IO使用多线程,处理数据读写和协议解析,这是因为redis性能瓶颈在于网络IO而非CPU,使用多线程提高IO效率,从而提高redis性能。

        2.redis事务

                redis事务本质是顺序性、一致性、排他性地执行一个队列的一系列命令,

                流程        MULTI(开启事务)

                                命令队列

                                EXEC(执行事务)、DISCARD(撤销事务)

        3.hash冲突

                hash冲突:不同的值落在一个 hash表中,

                解决:链式Hash

        4.生产RDB期间可以同时写吗

                可以,RDB手动触发时,dbsave是异步另起一个线程进行RDB。

        5.Redis底层使用什么协议

                RESP        redis Serilzation Procotol 转为Redis设计的序列化实例,它有简单实现、解析速度快,可读性好等优点。

                

  • 4
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值