Daily Plan
更新: 5/3/2025 字数: 0 字 时长: 0 分钟
#todo
- [ ]
Daily Study
更新: 5/3/2025 字数: 0 字 时长: 0 分钟
空结构体的应用
#go 参考链接:Go 空结构体:零内存的魔力-阿里云开发者社区 两种定义方式:var e struct{}
, type EmptyStruct struct{} var EmptyStruct
特点:
- 零内存占用
- 地址相同
- 无状态 主要有三个应用场景:
- 实现set集合:基于map[T]struct{}
- 用于通道信号:使用一个空结构体来通知goroutine停止工作,主要是用
close(quit)
- 作为方法接收器
defer的使用
#go defer的几个核心点:
- 延迟执行:在函数结束时执行,包括正常返回或遭遇 panic。
- 栈式执行顺序:后定义的
defer
先执行(LIFO)。 - 参数预计算:
defer
语句定义时即计算并固定参数值。 - 值传递原则:
defer
拷贝参数,使用定义时的值。 - 环境变量捕获:在
defer
中可以跟一个闭包,闭包可以捕获环境变量,当然这包括具名返回值。 具体应用:
- 文件关闭,锁释放,资源回收,数据库事务回滚
- 错误处理,defer和recover,来防止程序因为panic而终止,做一些性能监控
snowflake
#go
详解:深度思考:雪花算法snowflake分布式id生成原理详解-阿里云开发者社区
定义
Snowflake算法的原理相对直观,它负责生成一个64位(long型)的全局唯一ID,这个ID的构成包括:1位无用的符号位、41位的时间戳、10位的机器ID以及12位的序列号,除了固定的1位符号位之外,其余的三个部分都可以根据实际需求进行调整: 1、41位时间戳:这部分能够表示的时间跨度为(1L<<41)/(1000L*3600*24*365)
,即大约69年。 2、10位机器ID:可以唯一标识最多1024台机器,如果需要对互联网数据中心(IDC)进行划分,可以将这10位拆分为两部分,例如各5位,这样,系统就能够表示最多32个IDC,且每个IDC下可以容纳32台机器。 3、12位自增序列号:用于在同一毫秒内生成多个ID,最多可以表示2^12个不同的ID,因此,理论上,Snowflake算法能够达到的每秒查询率(QPS)约为409.6
万。 ![[attachments/1744619690874_d.png]]
优缺点
优点
- 毫秒数在高位,自增序列在低位,整个ID都是趋势递增的。
- 可以不依赖数据库等第三方系统,以服务的方式部署,稳定性更高,生成ID的性能也非常高。
- 可以根据自身业务特性分配bit位,非常灵活。
缺点:强依赖机器时钟,如果机器上时钟回拨,会导致发号重复或者服务处于不可用状态。 解决方法
- 时间戳自增彻底解决时钟回拨问题:自定义一个时间戳增加的方法,例如序列号满后,时间戳+1
- 缓存历史序列号缓解时钟回拨问题:缓存了2000ms的序列号,如果发生时钟回拨,且回拨范围在2000ms内,就从缓存中取序列号自增,超过2000ms回拨,就抛异常,故障转移,将请求分配到正常机器。
总结
1、在分布式系统中生成全局唯一的ID至关重要,目前,业界广泛采用的方案包括数据库号段算法和雪花算法,这些算法不仅在大厂中得到了广泛应用,还催生了诸多开源项目,例如百度的uid-generator、美团的Leaf以及滴滴的TinyId等。
2、雪花算法以其简单高效而著称,其核心在于结合时间戳、机器ID和序列号来生成64位的唯一ID,该算法生成的ID整体上呈递增趋势,确保了全局唯一性,同时性能表现优异。雪花算法提供了高度的灵活性,允许根据实际需求自定义各个组成部分的bit位数,若需提升QPS(每秒查询率),可适当增加序列号所占的bit位数。
3、尽管雪花算法具有诸多优点,但它对机器时钟的强依赖性也带来了时钟回拨问题_,为应对这一问题,开发者们提出了多种解决方案,主要分为避免和缓解两大类。常见的方法包括使时间戳自增以摆脱对机器时钟的依赖、利用缓存来存储序列号,或等待时钟自行校正等。每种方法都有其独特之处,只有正确利用它们的优点,才能最大限度地提升系统性能。
4、雪花算法ID生成器的使用方式灵活多样,其中远程发号器和本地直接生成ID是两种主要方式。远程发号器需要确保高可用性,以满足分布式系统中的需求;而本地直接生成ID则省去了远程请求的开销,因此在性能上更具优势。然而,本地生成方式也带来了机器ID管理的挑战,因为一旦某个机器ID被使用,它就不能再被其他机器重复使用。为了应对这一挑战,开发者们通常利用MySQL或ZooKeeper等工具来进行机器ID的管理和分配。
Daily Problem
更新: 5/3/2025 字数: 0 字 时长: 0 分钟