> # 数据一致性 - 强一致性: 任何时刻,所有节点看到的数据都是相同的,读操作能立即看到最新写入的数据 - 有序执行(线性一致性) - 无序执行 (顺序一致性) - (XA) - 弱一致性: 读操作可能看到旧数据,并不能保证所有节点的数据完全同步 - 有序执行 (因果一致性) - 无序执行(最终一致性) - Kafka > # 秒杀系统 - 用Redis 缓存数量, 每次请求读取商品库存, - 库存>0, 库存-1, 返回成功, (需要原子性处理) - 库存<=0, 返回失败 > # 多个数据修改的时候怎么确保一致 - 强一致性还是最终一致性? - 是不是同一个库, 同一个服务, 同一个事务 - 强一致性: 实时一致,适合对数据准确性要求高的场景,通过数据库事务、锁机制实现 - 最终一致性:允许短暂不一致,适合高并发但对实时性要求不高的场景,依赖异步消息或副本同步 - 扣余额 → 减库存 → 创建订单(全部在一个事务) 强一致性, 但是锁的时间比较长 - Saga 是一种分布式事务模式,通过**本地事务 + 补偿事务**实现最终一致性 - Seata四种事务模式AT、TCC、SAGA、XA详解: https://baijiahao.baidu.com/s?id=1777717003459842931&wfr=spider&for=pc | **模式** | **一致性** | **性能** | **实现复杂度** | **业务侵入性** | **适用场景** | | --- | --- | --- | --- | --- | --- | | AT | 最终一致性 | 高 | 低 | 无 | 单数据库分库分表 | | TCC | 强一致性 | 高 | 高 | 高 | 金融交易、高并发场景 | | SAGA | 最终一致性 | 高 | 中 | 中 | 跨服务复杂业务流程 | | XA | 强一致性 | 低 | 低 | 无 | 跨数据库强一致性场景 | > # Redis 单线程为什么这么快 - 内存操作 - Redis 使用 I/O 多路复用技术(如`select`、`epoll`、`kqueue`),单线程可以同时处理多个连接请求,避免了阻塞等待 - 高效的数据结构: 跳跃链表, 压缩列表, 紧凑列表 > # Redis 哨兵模式和集群模式 - redis 持久化的时候会 会`fork`一个子进程 - Redis 哨兵模式: 从复制(Master-Slave)+ 自动故障转移 - Redis Redis Cluster(集群模式) : 采用 **分片(Sharding)**,每个节点负责一定范围的槽位 ~~~ root@winnie:/usr/local# /usr/local/redis-5.0.4/src/redis-cli --cluster create 192.168.1.170:8001 192.168.1.171:8003 192.168.1.172:8005 192.168.1.170:8002 192.168.1.172:8006 192.168.1.171:8004 --cluster-replicas 1c >>> Performing hash slots allocation on 6 nodes... Master[0] -> Slots 0 - 5460 Master[1] -> Slots 5461 - 10922 Master[2] -> Slots 10923 - 16383 ~~~ - slot : Redis Cluster 采用 **CRC16(key) % 16384** 计算 key 对应的 slot: - 使用 **哈希标签 `{}`**,如 `user:{id}`,所有 `{id}` 相同的 key 都会落在同一个 slot > # list 怎么确保输出有序 ``` LPush demo1 key1 key2 key3 key4 key5 key6 key7 key8 key9 key10 LRANGE demo1 0 4 // 输出 key10 key9 key8 key7 key6 LRANGE demo1 5 9 //输出 key5 key4 key3 key2 key1 LPUSH demo1 key11 LRANGE demo1 5 9 //输出 key6 key5 key4 key3 key2 (如果有新数据插入和删除,会导致数据重复或丢失) ``` ``` LPush demo1 key1 key2 key3 key4 key5 key6 key7 key8 key9 key10 LRANGE demo1 0 4 // 输出 key10 key9 key8 key7 key6 LPUSH demo1 key11 LPOS demo1 key6 //获取最后一个元素的游标 LRANGE demo1 6 10 //下一页游标加一开始 (两个命令需要原子性) ``` > # Kafka - Kafka 怎么确保消息有序 - 同一分区内是有序的, 不同分区间顺序无法保证 - **指定 Partition**:直接控制消息进入哪个 Partition - **使用 Key**:相同 Key 的消息进入同一个 Partition - 自定义分区逻辑 - **单 Partition 的吞吐量有限**, - 当 Kafka 消费速度突然变慢,导致消息堆积时,可能的原因有很多。以下是一些常见的原因及其排查方 - 生产消息变多 - 消费者因某些原因执行时间长 - Rebalance 新消费者数据发生变化, 需要重新分配(某些加到因消费时间长被提出) - 节点负载过高