最近感悟

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高在哪里
          • 日志大多了
          • 配置/路由频繁变更导致的原子竞争/锁竞争
        • 扩容节点?
      • 请求过载
        • 降流量,业务方?主动限流?
      • 资源滥用
        • 连接数频繁更新,不稳定

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

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