blog review 第二十四期
最近感悟
混
https://decentralizedthoughts.github.io/2020-12-12-raft-liveness-full-omission/
https://quickwit.io/blog/compressed-indexable-bitset
https://justinjaffray.com/joins-13-ways/
https://dotat.at/prog/qp/README.html
https://mp.weixin.qq.com/s/sbY0g65nETTbqPjV5MC80w?vid=1688851418274222
HLC
Physical Time Logical Clock PT组成作为逻辑时钟的高位, LC作为低位。
比如我们可以采用一个64bit的整数来存储一个HLC timestamp,那么这里简单定义,高32bit存储PT,低32bit存储LC。
每一个节点除了有一个HLC Clock,还有一个物理时钟(physical clock),这个物理时钟可以假设是任何的物理时钟,比如ntp协议,或者google的true time协议,这里对于物理时钟没有任何要求,物理时钟可以跳变,也可以回退,允许存在误差。
一个HLC Timestamp比较大小,也是先比较 physical time,如果physical time相等,再比较logical time
深入理解 Linux 内核–jemalloc 引起的 TLB shootdown 及优化
如果有IPI,需要关注一下是不是jemalloc帮倒忙了
watch -d -n 1 "cat /proc/interrupts | grep TLB" #观察数量
perf top #smp_call_function_many
ls /proc/*/maps | xargs grep jemalloc #观察jemalloc
strace -f -p 1510 2>&1 | grep madvise #观察有没有 MADV_DONTNEED
解决办法
MALLOC_CONF=dirty_decay_ms:-1,muzzy_decay_ms:-1
why this is bad to use XFS file-system without d_type support , regarding to docker
mkfs.xfs -f -n ftype=1 /dev/sda4
I/O Acceleration with Pattern Detection
一些设计的快速估算
访问密度
T = (QPS + TPS*N) / TotolStorageG
数据规模
一亿条x4KB = 400G数据 一亿八个零,去掉九个0是G,0.1 x 4000 = 400G
云上机器SSD是 PM9A3,查了一下资料,国产固态新品基本上都比这个盘效果好。比如致态Tiplus 7100。我得买点这个
信息来自 techpowerup 以及这个 https://www.zhihu.com/tardis/zm/art/580123162?source_id=1003
磁盘型号 | 顺序读带宽 | 顺序写带宽 | 随机读IOPS | 随机写IOPS |
---|---|---|---|---|
PM9A3 | 6800 MB/s | 4000MB/s | 1000k IOPS | 180k IOPS |
致态TiPlus7000 | 7000 MB/s | 6100 MB/s | 970k IOPS | 770k IOPS |
有群友反应消费级磁盘会降速。需要重新测试一下,我怀疑是随机读写导致的碎片降速
一个盘2T, 每个分片10G,保留25%容量用来compact,也就还剩150个db,假设每个都是一个副本的一个分片(避免多个分片落在同一个盘上一崩崩俩)也就是150个副本
元数据信息,假设一个副本的所有分片信息,都存,一条2K,2K * 150 一个节点的量。节点和磁盘数字正相关,元数据节点要考虑数据路由管理的限制
什么时候会修改元数据
- 主动迁移,腾空机器,均衡机器
- 被动迁移,坏盘
-
副本元数据变动
- 更改kv引擎的配置参数,更改表结构schema,复制组角色变化(这个可能频繁)
copyset设定
copyset原理,划分了不同的隔离域,例如标准集群中,选取3个满足可用区标准的27台机器为一个管理单元, 并且保证同一个AZ内的9台机器属于3个不同的机架,并根据机架关系,27台机器划分出9个升级域 同一个Partition的不同副本一定分散在不同的升级域内, 以此来保证在坏盘、死机、机架掉电以及机房故障等场景下,依然可以保证服务高可靠和高可用
如何全局中心来调度?
- 还是主动迁移被动迁移,raft副本坏了可以快速分配log复制模块,只保证日志正确就行,witness,可以不成为主,只要保证复制就行,节点恢复正常自动退出
- 采集信息,根据访问密度分出几档,然后调度迁移/切主
k8s信息 https://www.huweihuang.com/kubernetes-notes/code-analysis/kube-controller-manager/sharedIndexInformer.html
Measuring Memory Subsystem Performance
介绍几种测量cache使用的工具
代码在这 https://github.com/ibogosavljevic/johnysswlab/blob/master/2023-07-metrics/multithreading.cpp#L60
工具是这个 https://github.com/RRZE-HPC/likwid
重新考虑编码问题
常规的kv编码就是TLV格式
总长度 + key 长度 + key + value1长度 + value1 + value2长度 + value2
对于kv引擎来说,key单独抠出来,value加上一些属性,比如version/ttl/子keysize 等等,也可以不需要size
多个value怎么存?
- 拆成hash模式,key链,穿起来,pika的编码层就是这样的
- metakey fieldkey -> value 类似TLV 是length value 模式 -> 放在后面也可以?更方便comparetor?不然compare得跳过开头的长度, 其实理论上差不多
- 兼容问题,是否需要编进去一个encode_type
- 是否需要分片hash?
- 是否需要slot级别的scan?这种scan其实对全局scan影响很大。我觉得不是很有必要,如果需要,编码里还得加个hashkey(int32)
- 更细粒度的分裂/合并,不过你理论上已经有了这个信息(路由)了,编到key里有点多此一举,除非你需要特别精细的力度,抓到热key然后把这个key对应的hashkey范围撕出来
- 对于range路由,完全没用
- 编成巨长的一行,protobuf/fbs
服务定位思路 runbook
client→gateway→database
网络故障?iptables?DNS?路由(交换机)挂了?
集中点 ? gw单点? db单点? dbs单分片? dbs单key? 表集中?
-
gw单单点延时高 用户请求不均? 机器有问题?宿主机?
- jemalloc TLB shutdown?
-
表流量突增?
- gw过载,延时升高
- cpu过载 top
- perf分析CPU高在哪里
- 日志大多了
- 配置/路由频繁变更导致的原子竞争/锁竞争
- 扩容节点?
- perf分析CPU高在哪里
- 请求过载
- 降流量,业务方?主动限流?
- 资源滥用
- 连接数频繁更新,不稳定
- cpu过载 top
- gw过载,延时升高
https://github.com/maxi-k/btrblocks
有点意思,标记一个TODO
降冷的一些思考
对接对象存储平台,可以搞个fake dbserver直接充当这个效果
需要自己设计一套文件格式,比如rocksdb SST格式,来存储,另外,元数据需要上层存一下,cache住。等于变相实现一套文件系统,不过接口简陋
缓存就直接全量缓存一下meta和文件。还涉及到升热/meta管理之类的问题
为了避免浪费对象存储IO,还得bloomfilter
或者换一种思路,接入分布式FS,比如juiceFS,他底层对接对象存储,上层直接使用文件API,伪装成文件系统的对象存储,彳亍。这样原来的流程没有任何变化,但是引入中间层可能开销大?
https://github.com/DolevAdas/Jiffy
这个代码可以验证一下,对比一下
关于多region的一些思考
其实就是CDC转发
要求CDC高效
- 类似MQ的发送一次能力,保证消费
- 本质是WAL流(binlog流),订阅能力其实可以按照MQ那样扩展开,并且以多种形态落地,比如存到冷备(对象存储,以及伪装成文件系统的对象存储)
数据一致性问题,也就是Anti-entropy merkle-tree这坨,分片力度
- 从哪个时间点开始比较呢?,如果备份少key但那部分key正在同步中呢?
- 需要一个合理的检查窗口,忽略一部分key
- 如果不同,怎么修复?
- 源的数据分片直接拷贝过来,有点重,还得考虑期间的同步问题
- 扫描分片对应的key
- 直接从源region抠出来key value set过去,手动
- 巡检任务,自动重放损坏的kv log,重新同步
PostgreSQL: No More VACUUM, No More Bloat
解决方法就是重新实现一个pg https://github.com/orioledb/orioledb
主要是改log log膨胀恐怖,那就让log可以原地改?
统计网卡流量
sar -n DEV 1 2
cat /proc/net/dev
iftop -i eth0 -t -s 30 -L 100
netstat -s
Architecture decisions in Neon
多一跳啊,有必要吗?
Prevent Locking Issues For Updates On Counters
还是分槽,直接贴代码吧,没啥新鲜的
CREATE TABLE pageviews_counts (
url varchar(255) PRIMARY KEY,
fanout smallint NOT NULL,
count int
);
CREATE UNIQUE INDEX pageviews_slots ON pageviews (
url, fanout
);
// 更新
INSERT INTO pageviews_counts (
url, fanout, count
) VALUES (
'/home', FLOOR(RAND() * 100), 1
) ON DUPLICATE KEY UPDATE count = count + VALUES(count);
Bounded Staleness Read
Yugabyte DB:https://blog.yugabyte.com/reads-in-yugabytedb-tuning-consistency-latency-and-fault-tolerance/
OceanBase DB: https://www.oceanbase.com/docs/oceanbase-database/oceanbase-database/V2.2.77/standby-cluster-read-service
Azure Cosmos DB:https://docs.microsoft.com/zh-cn/azure/cosmos-db/consistency-levels
Google Spanner DB:https://cloud.google.com/spanner/docs/timestamp-bounds
方案 | 条件 | 时钟 | |
---|---|---|---|
CosmosDB | 时间T,落后K个版本 | 5秒/10个,如果是多地复制的100秒100000个版本 | HLC |
Spanner | 时间 | 10秒 | TrueTime |
OceanBase | 时间 | 5秒 | TSO |
YugabyteDB | 时间 | 60秒 | HLC |
crdb? | HLC |
一个协程实现
https://github.com/skyfireitdiy/cocpp
https://xie.infoq.cn/article/1541e19a74025b567151a1e6e
周末看看
Beyond malloc efficiency to fleet efficiency: a hugepage-aware memory allocator
todo
Changing std::sort at Google’s Scale and Beyond
todo
Fastest Branchless Binary Search
template <class ForwardIt, class T, class Compare>
constexpr ForwardIt sb_lower_bound(
ForwardIt first, ForwardIt last, const T& value, Compare comp) {
auto length = last - first;
while (length > 0) {
auto rem = length % 2;
length /= 2;
if (comp(first[length], value)) {
first += length + rem;
}
}
return first;
}
Optimizing a ring buffer for throughput
这哥们博客挺好的
https://github.com/rigtorp/SPSCQueue