Redis6学习整理

1. Web2.0时代,用户访问量大幅提升,面临的挑战有哪些? 
    * 应用服务器: CPU/内存压力 ==> 采用集群方式, 部署多台应用服务器(前置负载均衡组件)
    * 数据库: IO压力 ==> NoSQL 缓存数据库, 针对不同数据结构类型改用性能优先的存储方式: 列式数据库, 文档数据库
2. 集群环境下的session共享问题有哪些解决方案
    * 方案1: 存在cookie里. 不安全
    * 方案2: 存在数据库里. 大量的IO效率问题
    * 方案3: session复制. 数据冗余, 节点越多浪费越大
    * **方案4: 缓存数据库. 完全在内存中, 速度快且数据结构简单**
    * 方案5: ip哈希
3. 常见的负载均衡组件有哪些, 各自有什么特点? 
        * 硬件: F5
        * 软件: nginx, haproxy, LVS ==> 详细参考 https://blog.csdn.net/mashuai720/article/details/78625678
            - nginx: 工作在网络7层, 安装配置简单, 仅能支持http(s)和Email协议, 对请求异步处理(可以减轻服务器压力), 可以做Web服务器
            - haproxy: 支持TCP(4层)/HTTP(7层), 支持虚拟主机, 能够Session保持/Cookie引导等, 不能做Web服务器
            - LVS: 工作在网络4层, 稳定可靠, 不支持正则, 不能动静分离, 配置相对复杂
        * 总结: 网站建设初期,可以选用Nginx、HAProxy作为反向代理负载均衡(流量不大时,可以不选用负载均衡),因为其配置简单,性能也能满足一般业务场景。如果考虑到负载均衡器是有单点问题,可以采用Nginx+Keepalived/HAproxy+Keepalived避免负载均衡器自身的单点问题。网站并发到达一定程度后,为了提高稳定性和转发效率,可以使用lvs,毕竟lvs比Nginx/HAProxy要更稳定,转发效率也更高。

    * 常见的负载均衡算法
        * rr轮询, wrr带权轮询, lc最小连接, wlc带权最小连接, source(原地址保持)
4. 常见的NoSQL数据库有哪些, 简单说明下
    * Memcache: 数据都在内存中(一般不持久化), 仅支持简单的key-value模式(支持类型单一)
    * Redis: 几乎覆盖了Memcache的绝大部分功能, 支持就持久化, 支持多种数据结构
    * MongoDB: 文档型数据库, 数据都在内存(不足时把不常用的保存到磁盘), 虽然是key-value模型, 但是对value(json)提供了丰富的查询功能
    * HBase: Hadoop项目中的列式数据库, 目标是处理数据量非常庞大的表, 可以用普通计算机处理超过10亿行数据
    * Cassandra: Apache下的列式数据库, 目标在于管理由大量商用服务器构建起来的庞大集群的海量数据集(数据量通常达到PB级别)
    * Neo4j: 图关系型数据库, 主要应用在社会关系, 公共交通网络, 地图及网络拓扑
5. 简单说一下Redis的特点
    * 开源的key-value数据库
    * value支持的类型比较多: string, list, set, zset, hash; 新数据结构: Bitmaps, HyperLogLog, Geospatial
    * 支持各种不同方式的排序
    * 缓存在内存中的, 会周期性的把更新的数据写入到磁盘(RDB) 或 修改操作写入追加记录(AOF)
    * 实现了master-slave主从同步和集群
6. Redis的应用场景有哪些? 
    - 配合关系型数据库做高速缓存
        * 集群下的session共享: Shiro会话, JWT验证
        * 高频次, 热点数据的缓存, 降低数据库IO: 比如用户是否为管理员
    - 多样的数据结构存储持久化功能
        * 最新N个数据: 通过List实现按自然时间排序
        * 排行榜(TopN): 利用zset
        * 时效性数据(比如手机验证码): Expire过期
        * 计数器(秒杀): 原子性, 自增incr, 自减desr
        * 去重大量重复数据: 利用set集合
        * 构建队列: 利用list集合
        * 发布订阅消息: pub/sub模式
    - 其他
        * 合同生成进度等
        * 外部数据访问有效期
7. Redis的命令工具有哪些, 都是做什么的? 
    - redis-benchmark: 性能测试工具
    - redis-check-aof: 修复有问题的AOF文件
    - redis-check-dump: 修复有问题的dump文件
    - redis-sentinel: 哨兵, 集群使用
    - redis-server: 服务启动命令(注意启动目录默认即dump.rdb文件所在位置)
    - redis-cli: 客户端, 操作入口
8. Redis的启动关闭与相关知识
    - redis-server /etc/redis.conf (daemon改为yes后台启动)
    - redis-cli  进入后shutdown 或 直接 kill
    - 默认16个库, select <dbid>来切换. dbsize/flushdb/flushall
    - 单线程+多路IO复用技术: 使用一个线程来检查多个文件描述符(Socket)的就绪状态
    - 原子操作: 指不会被线程调度机制打断的操作
9. Redis的常用数据类型, 操作命令及底层数据结构
    - 字符串: 数据结构为简单动态字符串, 采用预分配冗余空间的方式减少内存频繁分配. 小于1M扩容时加倍, 超过1m扩容一次多扩1M. 字符串最大长度为512M
        ```
        设置/获取/删除, 是否存在/查看类型, 设置过期/查看还有多久过期, 总共有哪些key
        set/get/del  , exists/type, expire/ttl, keys * 
        unlink key: 根据value选择非阻塞删除(仅将keys从keyspace元数据中删除, 真正删除后续异步操作)
        append/strlen/setnx, incr/incrby, decr/decrby
        mset/mget/msetnx, getrange/setrange, setex <key> 过期时间, getset: 以新换旧
        ```
    - 列表List: 数据结构为快速链表quicklist. 列表元素较少时使用一块连续内存, 这个结构是ziplist(压缩列表).数据量比较多时才会改为quicklist(普通链表和ziplist组合)
        ```
        lpush/rpush, lpop/rpop, rpoplpush, lrange, lindex, llen, linsert, lrem, lset
        值在键在, 值光键亡. -1右边第一个, 0 -1 表示获取所有
        ```
    - 集合Set: 数据结构是dict字典, 字典采用哈希表实现. 添加/删除/查找的复杂度都是O(1)
        ```
        sadd, smembers, sismember, scard, srem, spop, srandmember, smove, sinter, sunion, sdiff
        ```
    - 哈希Hash: 对应的数据结构有两种, ziplist(压缩列表), hashtable(哈希表). 当field-value长度较短且个数较少时使用ziplist, 否则使用hashtable. 特别适用于存储对象.
        ```
        hset/hget, hmset, hexists, hkeys, hvals, hincrby, hsetnx
        ```
    - ZSet: 有序set(SortedSet), 每个成员都关联了一个评分(score). 底层使用了两种数据结构. hash(value和score)和跳跃表(排序)
        ```
        zadd, zrange, zrangebyscore, zrevrangebyscore, zincrby, zrem, zcount, zrank
        ```
10. Redis的常见配置有哪些? 
    - 网络: bind, protected-mode, port, timeout, tcp-keepalive
    - 通用: daemonize, pidfile, loglevel, logfile, databases
    - 安全: requirepass
    - 限制: maxclients, maxmemory, maxmemory-policy, maxmemory-samples
11. Redis的发布和订阅
    - 订阅: subscribe <channelName>
    - 发布: publish <channelName> <message>
12. Redis新数据类型
    - Bitmaps: 实际上它就是字符串, 但是可以对字符串的位进行操作. 可以想象为一个以位为单位的数组, 数组的每个单元只能存储0和1, 数组的下标叫做偏移量
        ```
        setbit/getbit, bitcount, bitop and(or/not/xor)
        ```
    - HyperLogLog: 用来做基数统计的算法(独立访客,独立IP数,distinct count). 在输入元素数量或体积非常大时, 计算基数所需的空间总是固定的, 并且是很小的
        ```
        pfadd, pfcount, pfmerge
        ```
    - Geospatial: GEO类型经纬度, 设置/查询/范围查询/距离查询/经纬度Hash等操作
        ```
        geoadd, geoops, geodist, georadius
        ```
13. Redis事务的使用与说明
    - multi, exec, discard: 组队和执行两个阶段
    - watch: 监视1个或多个key, 如果事务在执行之前key被其他命令改动, 那么事务将被打断
    - Redis事务的特性
        * 单独的隔离操作: 不会被其他客户端发送来的命令打断
        * 没有隔离级别概念: 提交之前都不会实际被执行
        * 不保证原子性: 如果有1条命令执行失败, 其后的命令仍然被执行, 没有回滚
    - LUA脚本
14. Redis的持久化
    - RDB: (dump.rdb)在指定的时间间隔内将内存中的数据集快照写入磁盘(Snapshot快照), fork子进程进行持久化
    - AOF: (appendonly.aof)以日志的形式记录操作写操作(增量保存), 只许追加文件但不可以改写文件. 同时开启默认取AOF的数据
15. Redis的主从复制, 哨兵, 集群
16. Redis应用问题解决
    - 缓存穿透: 不存在的key压垮数据库
        * 方案1: 对空值缓存
        * 方案2: 设置访问白名单
        * 方案3: 布隆过滤器
    - 缓存击穿: 热点key过期的瞬间压垮数据库
        * 方案1: 预热热门数据
        * 方案2: 实时调整热门数据的过期时长
        * 方案3: 使用锁
    - 缓存雪崩: 大量key短期内同时过期
        * 方案1: 构建多级缓存架构
        * 方案2: 使用锁或队列
        * 方案3: 设置过期标志更新缓存
        * 方案4: 将缓存失效时间分散开
    - 分布式锁: 分布式集群系统后, 需要一种跨JVM的互斥机制来控制共享资源的访问
        * 方案1: 基于数据库实现分布式锁
        * 方案2: 基于缓存(Redis等), 性能最高
        * 方案3: 基于Zookeeper, 可靠性最高
17. Redis6的新功能
    - ACL: Access Control List(访问控制权限), 对用户进行更细粒度的权限控制
    - 多线程: (默认关闭)指客户端交互部分的网络和IO模块多线程, 执行命令依然是单线程
原文地址:https://www.cnblogs.com/hepengju/p/14801258.html