缓存
有本地缓存和分布式缓存两种类型
redis
优点是C实现的单线程内存数据库,并且支持持久化和集群
redisson客户端实现了分布式的自增ID以及可重入和自动续期的分布式锁redLock
包含了SDS,linkedlist,ziplist,quicklist,dict,skiplist以及intset7种底层数据结构类型
redisobject是底层通用对象,包含了数据类型,底层数据结构类型,lru时间和引用次数等元数据信息以及指向底层数据结构的指针
包含了string,hash,list,set,zset 5中数据类型,其中string的底层数据结构是SDS,当内容是int时redisobject的指针覆盖为数字,内容为短字符串时SDS与指针相连,内容为长字符串时指针指向SDS地址,应用场景是分布式锁以及分布式ID
包含了bitmap,hyperloglog以及GEO三种扩展类型,GEO的底层是zset,将经纬度经过GEOHASH后得到score,GEOHASH是按照四象限将经纬度编码,编码后的score相似则两个经纬度位置离得越近
redis业务场景包括分布式ID,分布式session,时间序列数据查询redistimeseries,集合基数UV统计hyperLoglog,消息队列Streams,缓存以及秒杀。缓存的读写策略分为旁路缓存和读写缓存,旁路又分为先删缓存还是先更新数据库,读写缓存分为同步双写或者异步MQ写回redis,秒杀的话注意查库存和扣减库存需要同在redis的一个事务中保证数据一致性
redis的删除策略分为过期策略和淘汰策略,过期策略有定期采样删除和惰性删除,淘汰策略分为按照过期时间排序,LRU以及LFU,LFU就是将redisobject的lru时间拆分为lru时间和访问次数counter,counter最大255,非线性增长,淘汰时先判断counter。LFU可以解决缓存污染问题
原子操作包括单命令操作和LUA脚本
redLock的可重入通过hash表实现,可重试通过订阅解锁消息实现,自动续期通过看门狗实现,高可用通过多节点加锁实现
redis事务保证exec执行前的原子性,exec之前的隔离性通过watch命令保证,通过AOF和RDB保证持久性
通过设置基线性能判断redis是否变慢,变慢的原因有内部阻塞操作如bigkey和RDB加载,可以通过异步线程解决;内存碎片,原因是jemalloc只分配2的n次幂空间,可以通过自动清理解决;缓冲区溢出,包括客户端输入输出缓冲区和主从集群的复制缓冲区和复制挤压缓冲区
主从数据全量同步通过主库发送RDB文件以及复制缓冲区缓存期间写命令完成。主从级联可以缓解主库压力;网络中断时写命令缓存在复制挤压缓冲区中,该缓冲区满了则触发全量同步
通过哨兵实现主从切换,通过打分选定新主库
哨兵集群通过发布订阅通信,通过客观下线实现主从切换
切片集群通过一致性哈希的slot缓存数据实现分布式存储,slot信息保存在每一个实例中,而codis的元数据保存在zk中,proxy是无状态的
缓存雪崩通过双key策略或者小随机数过期时间解决
缓存穿透通过缓存无效key或者布隆过滤器解决,布隆过滤器本质是多个哈希算法
缓存击穿可以通过分布式锁或者逻辑过期解决
一致性问题通过重试解决,如果是先删除缓存方案则可以通过延迟双删解决
脑裂数据丢失来源于错误判断主节点客观下线,导致双主节点,通过保证主库有超过一半从库的方案解决
数据倾斜包括bigkey问题和hotkey问题,hotkey通过多副本解决,避免bigkey
redis的io模型是事件驱动的IO多路复用
RDB内存快照的优点是加载速度快,可以通过bgsave通过子进程写入,更新时写入使用copyonwrite策略
AOF是写后日志,并且有no,everysec以及always三种写入策略,aof重写是遵循一个拷贝两处日志规则
当然也有非内存的利用利用rockDB存储的SSD版本的redis
mongoDB
主要由BSON,集合以及数据库组成,支持索引,事务以及分片集群,分片集群的单位是chunk,分片键避免连续且基数要大
分布式
基础是cap和BASE原则,基本可用,软状态以及最终一致性
调用方式可以通过http和rpc
netty是一个rpc的通信框架,特点是零拷贝和事件驱动
负载均衡算法包括轮询,最小连接和一致性哈希,框架有feign和ribbon等
注册中心由zk和eureka等,zk有临时节点和持久节点两种类型,通过watch可以实现节点监听,应用场景有分布式锁,心跳以及注册中心等
网关的作用有限流和认证,框架有gateway
限流算法包括计数器,滑动窗口以及令牌桶,可以通过redis实现,框架有sentinel等
分布式事务最终一致性方案有时间表配合定时任务以及消息队列事务消息,后者利用了事务消息的反查特性
强一致性方案有2pc方案,seata的AT和TCC模式都是2pc方案,AT利用了数据库事务以及全局锁并配置了日志表用于回滚适用于库存扣减,TCC则放弃了全局锁在代码层面实现资源预占用适用于资金转账
SAGA方案采用了弱一致性,每个事务独立运行,并统一配置补偿逻辑,适用于长事务逻辑如酒店预订
3pc的方案增加了cancommit的校验阶段,并在参与者引入了超时机制
分布式ID的要求是连续以及包含业务含义,可以使用数据库的号段模式,redis自增以及算法三种方案,算法包括UUID和雪花等,UUID是无序的,当然也可以包装成发号器服务
docker
dockerfile构建镜像
docker-compose对容器启动排版
es
一个index包括很多文档,文档中包含version以及score等字段
es包括多个lucene,一个lucene包括多个segment,segment是最小搜索单元,包含了倒排索引表,前缀树以及行式存储三部分
高性能高扩展方案是对index进行一致性哈希分片,每一个分片是独立的lucene,通过协调节点进行分片索引
高可用方案就是主从备份
写入时通过协调节点进行一致性哈希写入对应的分片
搜索时如果不提供ID,则协调节点先查询index所有分片,从倒排索引获取文档ID后,再去行式存储中获取完整文档再返回客户端;如果提供ID则直接取模算出分片节点
put是覆盖更新,post是增量更新,如果没变化version字段不变
reindex进行索引迁移
查询分为聚合查询,复合查询,全文检索,精确查询以及nested对象查询等
mapping描述和文档的结构,包括动态mapping以及常用的类型如字符串,数值,nested,date等。字符串又分为text可分词文本和keyword精确值
消息队列
应用场景有日志,订单超时(分布式事务回滚,延迟队列被动补偿,主动补偿),解耦,分布式事务反查,顺序保证,延时队列以及实时数仓接入等
rocketMQ
注册中心是nameserver,所有nameserver节点保存相同信息
broker存储topic,topic由queue组成,broker副本同步有同步复制和异步复制,同步复制是一半以上slave即可
topic消息包括简单消息(单向异步同步),顺序消息,延迟消息,事务消息等类型
消息存储于broker的commitlog中,queue只是记录消息的消费位置,写入commitlog有同步刷盘异步刷盘两种方式
生产者的负载策略是把消息均匀放在topic的每个queue上
消费者组中每个queue只能由一个消费者消费
常见问题包括可靠性投递,消息丢失,重复消费以及消息挤压
和kafka的区别在于,在架构上的减法(去掉ZK,以及使用broker而非分区副本),以及在功能上做加法(过滤消息,事务消息,延时消息,死信队列)
rabbitMQ
exchange通过消息的routing-key绑定到queue上,消费者订阅queue消费
kafka
高性能由消费者组以及分区提供,高扩展由broker提供,高可用由分区的副本机制提供,segment提供持久化能力,协调组件由zk变为了kraft,即broker之间的领导者选举
kafka快的原因在于0拷贝以及segment的顺序读盘
topic的分区内消息有序
分区的副本机制的follower不提供读写,延迟小的follower组成ISR
特殊的topic包括保存位移以及事务信息的topic
kafka是异步回调生产,可以通过设置key实现同类key发送到相同分区
生产者支持消息压缩
生产者会在一开始创建子线程就跟所有broker建立连接
kafka提供最多最少以及精确一次三种语义的可靠交付,精确一次通过幂等以及事务实现,幂等实现分区内精确一次,事务只实现了读提交隔离级别
消费者端在poll时才会连接协调者以提交位移以及leader副本以消费消息
消息消费有lag和lead两个指标
消费者实例不是线程安全,多线程可以通过事件驱动或者子线程里新建消费者的方案
消费者组中消费者挂了之后会触发重平衡
消费者位移信息可以在poll时自动提交也可以手动同步或者异步提交,过期位移信息通过logclear线程定期删除
位移重设可以通过时间维度也可以是位移维度
消费者组通过协调者实现重平衡,由消费者leader分配新的分区分配方案后发送给协调者广播给各消费者
消费者通过协调者提交位移,为了避免重平衡,应该把消息最大消费时间设置足够大以满足重消费逻辑
拦截器可以在消费者和生产者中设置,满足端到端的性能检测需求
segment写满后封存
broker请求处理时,请求通过分发线程传递给处理线程池再传递给IO线程池处理,处理线程从响应队列获取响应返回给客户端
leader的高水位领先于follower1轮会导致日志截断时数据丢失,kafka通过leaderEpoch机制解决,即记录每个leader版本第一次写入消息的位移值
broker通过控制器协调,控制器缓存zk中的元数据,第一个在zk中创建/controller节点的broker就是控制器
参数配置时需要配置不允许unclear副本即不在ISR的副本参与leader选举,会造成数据丢失
kafka支持动态参数,优先级高于静态参数
流处理包括connect组件连接上下游以及stream组件提供计算算子以及定义流和表,流表二元性即是时间窗口的汇聚将流变成了表
kafka只对已提交的消息做有限度的持久化保证,已提交即生产者消息的ack三种确认参数配置,不确认,leader确认以及指定副本确认
kafka调优的方向分为高吞吐和低延时两个方向