[re_1] const|cap|zookper|snowflake
CAP
CAP原则又称CAP定理,指的是在一个分布式系统中,一致性(Consistency)、可用
性(Availability)、分区容错性(Partition tolerance)。CAP 原则指的是,
这三个要素最多只能同时实现两点,不可能三者兼顾。
结合redis
CA - 单点集群,满足一致性,可用性的系统,通常在可扩展性上不太强大。
CP - 满足一致性,分区容忍性的系统,通常性能不是特别高。
AP - 满足可用性,分区容忍性的系统,通常可能对一致性要求低一些。
zookeeper
单机模式(保证CP)
- 最简单的部署方式,数据存在单个节点(含Redis进程和持久化存储)。
- 适合小型应用、开发或测试环境,优势是简单、低延迟、高性能。
主从复制(保证CP)
- 基于单机模式增加数据备份,分主节点和从节点。
- 主节点处理写操作,从节点复制主节点数据并处理读操作。
- 优点是提高可靠性(主节点故障可从从节点恢复)和可扩展性。
哨兵机制(保证CP)
- 在主从模式基础上,增加哨兵进程监视节点状态。
- 主节点故障时,哨兵自动将某个从节点升为新主节点,无需人工干预。
- 进一步提升集群可靠性,确保服务持续运行。
集群模式(保证AP)
- 多个节点分配数据,提升可扩展性和容错性。
- 每个节点处理自己的数据,节点失效时数据自动迁移到其他节点。
- 适合大规模部署,可灵活扩缩容,不影响系统性能和可靠性。
引申:Zookeeper
Zookeeper 通常被认为是保证 CP 的系统(遵循 CAP 理论中的一致性和分区容错性)。它专注于提供强一致性的分布式协调服务,比如分布式锁、服务注册发现等,在网络分区发生时,会优先保证数据一致性,可能暂时牺牲可用性。
const
C++里的 #define 能方便替换值,优点是让程序清晰、好改、执行快,但缺点是没类型检查;而 const 就是为了替代它,既保留优点又解决了这个缺点。
// #define 示例(无类型检查)
#define MAX_NUM 100
int a = MAX_NUM; // 替换为 int a = 100;
float b = MAX_NUM; //✅也能替换,无类型限制,可能隐藏问题
// const 示例(有类型检查,继承优点)
const int MAX_NUM = 100; // 明确int类型
int a = MAX_NUM; // 正常
float b = MAX_NUM; //✖️ 编译时会检查(可能警告类型转换)
存储
C++中const变量内存只在栈区或静态存储区,编译时不修改它的值的话,编译器会用临时符号表优化效率,不用纠结具体位置。
只读变量vs符号表
只读变量是内存中能看不能改的量,符号表是编译器里存真正常量的“小本本”。
// 1. 用字面量初始化的const常量,进入符号表(真正的常量)
const int a = 10; // "10"是字面量,a进入符号表
// 2. 用其他变量初始化的const,是只读变量(不进符号表)
int b = 20;
const int c = b; // 用变量b初始化,c是只读变量
// 3. 被volatile修饰的const,不进符号表(只读变量)
volatile const int d = 30; // 有volatile,d是只读变量
snowflake
- 分布式ID特点:要全局唯一、能递增、随时能生成正确ID,还得在高并发下性能好。
- 生成方案:有依赖数据库自增、UUID随机数、雪花算法这三种常见方式。
- 各方案优缺点:
- UUID:能保证唯一,但无意义且不递增,数据量大时查询慢。
- 数据库自增:读写分离时主节点易单点故障,分库分表后数据迁移合并麻烦。
- 雪花算法:Twitter开源,生成64位带时间顺序的纯数字ID,性能高、容量大,每秒能生成数百万自增ID;不过依赖系统时间,分布式多节点下若时钟有变化,全局ID可能不递增。
- Leaf(美团开源):能全局唯一、趋势递增,但依赖数据库、Zookeeper等中间件。
- 雪花算法细节:
- 是Twitter开源的分布式ID生成算法,生成64位长整数ID。
- 结构含无效位、时间戳(41位,可容纳约69年)、机器ID(10位,最多容纳1024个节点)、序列号(12位,每毫秒最多生成4096个ID)。
- 优点是全局唯一、自增有序、纯数字查询高效且不依赖数据库,适合分布式场景;缺点是依赖系统时间,分布式多节点时钟变化可能导致全局ID不递增
代码
实现雪花算法(Snowflake)的C++版本,用于生成分布式环境下的唯一ID,核心逻辑如下:
- 初始化时需传入数据中心ID和工作机器ID(各占5位,最多支持32个数据中心和32台机器)。
- 生成ID时,用当前时间戳(基于1970年起点,精确到毫秒)、数据中心ID、机器ID和序列号(12位,每毫秒最多生成4096个ID)组合成64位整数。
- 同一毫秒内生成多个ID时,序列号递增;跨毫秒则重置序列号;若时钟回拨会报错,确保ID不重复。
- 用互斥锁保证多线程安全,main函数中简单演示了生成10个唯一ID的过程。