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模块多线程, 执行命令依然是单线程