面向离职编程,把你每一行代码,每个文档,都当做离职交接文档。配置文件的详细描述,代码的打包,部署,

测试环境和正式环境的配置,TODO,如何扩展等

https://www.zhihu.com/question/68611994/answer/298467553

最近面试了一堆公司,看看大家都在忙什么

其实kv和存储距离很近,比如ceph用rocksdb存meta

AI公司很多场景要的是个牛逼点查的对象存储

和sue又讨论了一个场景,他有个导入服务和tendis,导入期间延迟升高

导入服务上传文件影响tendis网络延迟了,换成rsync就缓解了;

挺离谱的

ingest导致的升高,可能是memtable重叠导致的写停/compaction

和pika社区讨论到的zset问题

zrange等类似操作没有监控,没有有效的compact策略

而且readoption bound也没设置,prefix_extrator也没设置,我靠

统计操作数compact不是特别准,针对慢的搜索针对性compactkey更好一些

kvrocks做的是基于时间的compact。按理说zset数据特别多,数据混在一起

这种场景基于文件创建时间的排序不是能很好的compact到吧。不过他们社区并没有相关的反馈

ClickHouse Keeper: A ZooKeeper alternative written in C++

能嵌入到clickhouse 也能单独部署

更好的磁盘压缩率

jute.maxbuffer 坑 消息 默认1M cloud.tencent.com

zxid泄露问题

基于nuraft重写

todo 看nuraft

zippydb

For ephemeral data, ZippyDB has native TTL support where the client can optionally specify the expiry time for an object at the time of the write. We piggyback on RocksDB’s periodic compaction support to clean up all the expired keys efficiently while filtering out dead keys on the read side in between compaction runs.

分片管理有个shard manager,可以普通分片,也可以按照key的使用分布来分片,有个akkio服务,特殊处理news feed之类的业务

multipaxos 多写策略

一致性 可配置,可read your own write fast-ack或者线性一致性

事务支持

occ

epoch + write set

Conditional write 这玩意类似dynamo的设计 select for update?

How Facebook deals with PCIe faults to keep our data centers running reliably

简单来说就是定期检查PCIE状态,连接,带宽,分别计算

有个命令行能查接口

其他就是PCIE错误处理之类的

taobench

把ycsb-cpp改改,适配图数据库场景

有点意思

其实更多是mysql上建模图数据库的场景 TAO那种就是cache+mysql 优化cache设计

bytegraph好像也这样

避免在分布式系统中回退 fallback

考虑单机回退场景 malloc失败再来个malloc2 很难测 很难维护

再比如读cache读不到读db,这也是一种回退

分布式场景,回退,复杂度xN

怎么解决

  • 避免这么用,主动重试,而不是主动回退,增加冲击
    • 组件自身有修复机制,而不是靠调用方回退逻辑触发
  • 主动推送数据,这也是上面的修复机制的另一种说法
    • IAM场景,必须推,如果IAM挂了就完了
  • 回退逻辑由于不经常触发可能成为隐患,所以改成一种故障迁移逻辑更常见更可测,风险更低
  • 重试/超时不是回退。增加随机性,要增加监控,避免重试/超时成为风暴来源
  • 如果回退非常重要,那么要在测试中体现出来

这些要成为checklist

Cache made consisten

引入新节点Polaris 伪装成cache节点,发给其他cache一致性检查

检查可能有问题

  • 重试,避免误报报错
  • 时机不对,假阳性,polaris收到的cache变动已经是旧的了,新的还没过来

场景,x=3 version 4 查其他cache不存在,这个场景可能是x被删version3 也可能是x被删version5

这种场景只能 反查db来校正,但反查db可能导致后端被打爆。在重试无法解决的场景下

推迟反查,比如一分钟五分钟,之后反查。尽可能拉长窗口避免雪崩

上报指标 N个9在M分钟内 缓存一致

想提高9,就增加polaris服务 增加吞吐,聚集更多数据?perform aggregation over a longer time window.

写回时间窗导致的cache不一致问题

紫色时间窗

只能是记录事件时间序列来回溯?

这种数据也太多了,怎么维护的过来?

然后举了一个版本号相同但data不同的线上bug。

cache更新同时db也在写刷新淘汰缓存,存在这个时间窗,导致更新失败,触发失败淘汰旧key drop_cache(key,version)

但更新是根据version来清除的,version小于才会清除,实际上version相等了,导致key没淘汰掉。

感觉是版本号不够随机,不合理

版本号应该是个逻辑时钟

引入polaris这个checker框架能够更快速的告警发现bug,毕竟这种失败是比较静默的

海量数据问题

最近面试被面到好几次。没准备就是不行啊

简单思路

  • 分片缩小数据集(可能是hash也可能是范围) + hash统计 + 堆/快速/归并排序;
  • Bloom filter/Bitmap;
  • Trie树/数据库/倒排索引;
  • 败者树外排序
  • Map Reduce。

问题1 多个文件 大于内存 找公共部分/TopK /海量数据找TopK

一般都是hash分片,然后hashmap统计/ 堆排序

问题2 文本文件中频率最高的TopK /wordcount/搜索引擎

trie树构建 堆排序

问题3 1G数据 1M内存 找TopK

内存明显不够用,外排序

问题4 40亿数字集合和一个target,求是否在集合中

bitmap

问题5 亿级别数字 找出不重复的整数的个数

范围分片 + bitmap + bitmap合并

问题6 亿级数字,找中位数

范围分片 统计每个片的个数

Redis 中 BigKey、HotKey 的发现与处理

大key定义

  • list/zset > 10000
  • hash 总体大于100M

    热key定义

  • 满负载请求 70%单一key,执行大量无意义的processcmd
  • hash filed > 1000 size >1M hgetall
  • zset filed > 10000 zrange -> CPU 升高

大key带来多余的带宽/CPU占用 间接导致热key

热key多余的CPU使用可能导致业务错误

本质还是流量倾斜

如何发现

  • 常规 异步分析 scan + object freq 时效性问题
  • moniter 影响性能 类似方案已经不维护
  • 网络抓包可能性?tcpdump比较麻烦,ebpf感觉有可能,但没见谁用过,只提思路
  • 客户端统计 侵入性
  • proxy层统计 需要单独实现

如何解决?本质还是打散

  • 重组key 按照分片拆开(热key备份),分摊
  • 读热点?读写分离
  • proxy 可以query cache
  • 客户端缓存

京东hotkey方案

收集器,可定制key规则, 收集器将收集的key/传到jvm 缓存

基于etcd watch订阅key收集器

snmalloc

重点设计

Allocations on one thread are freed by a different thread

Deallocations occur in large batches

异步释放内存 - work steal内存管理降低延迟

大内存释放无锁

8 Practical Use Cases of Change Data Capture

  • 更新cache 案例 https://www.confluent.io/events/kafka-summit-london-2022/keep-your-cache-always-fresh-with-debezium/?source=post_page—–8f059da4c3b7——————————–

  • 更新 index 比如ES
    • 内存的index数据小,index的变化容易构建
  • OLAP数据导入 常规

  • 当复制同步用,比如账单
  • 当物化视图用,读写分离模式
  • 数据交换
  • 流数据处理聚集 flink
  • 订阅模式
    • 报表BI汇聚

Don’t use DISTINCT as a “join-fixer”

distinct暗含排序

select distinct join会多排序,浪费

peerdb 迁移为什么快

迁移pg的

We do this by logically partitioning the large table based on internal tuple identifiers (CTID) and parallelly streaming those partitions to Snowflake

学习的duckdb的经验,根据CTID并行化 https://duckdb.org/2022/09/30/postgres-scanner.html#parallel

SQL join flavors

一张图解释join,挺好的,马上就懂了

FIFO queues are all you need for cache eviction

感觉就是2Q的一种变种 代码在这 https://github.com/Thesys-lab/sosp23-s3fifo/blob/main/libCacheSim/libCacheSim/cache/eviction/S3FIFO.c

2Q原理

把被访问的数据放到LRU的缓存中,如果这个对象再一次被访问,就把他转移到第二个、更大的LRU缓存,使用了多级缓存的方式。

去除缓存对象是保持第一个缓存池是第二个缓存池的1/3。

Scaling data ingestion for machine learning training at Meta

特征存储是导入的,列举了几个他们的优化思路

首先是读取优化,特征本身是多个维度,只要某一个维度,完全可以列存避免读到别的数据

另外本身特征是多版本的,更适合列存,性能翻倍

对于DPP导入组件来说,这样优化,减少不必要的数据读,性能也有提升

map本身冲突?可以flaten优化省掉无意义读。也降低了服务内存使用

根据读取来重排数据,降低无意义的数据开销 这个思路有点意思。可能得采样读取信息,根据这个profile重新生成数据,哈哈,PGO

连接数超过连接池之后的行为是什么样的?临时连接?

请求限流,没有连接就等,间隔MS之后再创建新的连接,把连接创建平稳下来

问题:大量的连接等同于泄漏,即使平稳了曲线

全链路校验

rpc不偷懒。。加上checksum blake3

降冷

从Raft log层回写key→ cos文件位置的时候,一定要把降冷的kv的version带回来执行cas操作,只有当最新kv仍然是这个version时才能回写,不然可能会覆盖用户最新的写入

热点冲突

  • shared promise/query cache 合并
  • writecache 增加流程提前解锁,定期刷writecache - 延迟升高
SAMSUNG MZQL23T8HCLS-00B7C 210 3.84 TB 6900 MB/s 4100 MB/s 1 https://semiconductor.samsung.com/ssd/datacenter-ssd/pm9a3/mzql23t8hcjs-00a07/
INTEL SSDPF2KX038TZ 508 3.84 TB 6500 MBps 3400 MBps 1 https://www.wiredzone.com/shop/product/10021441-intel-ssdpf2kx038tz-3-84tb-drive-nvme-pcie-4-0-u-2-15mm-1dwpd-8252
SAMSUNG MZWLJ3T8HBLS-0007C 44 3.84 TB 7000 MB/s 3800 MB/s 1 https://semiconductor.samsung.com/ssd/enterprise-ssd/pm1733-pm1735/mzwlj3t8hbls-00007/
INTEL SSDPE2KX040T8 63 3.84 TB 2.93 GB/s 2.83 GB/s 1 https://www.wiredzone.com/shop/product/10028040-intel-ssdpe2kx040t8-hard-drive-4tb-nvme-pcie-3-1-3d-tlc-2-5in-u-2-15mm-1dwpd-2266
HFS3T8GETFEI-D430A 99 3.84 TB 6500 MB/s 3700 MB/s 1 https://product.skhynix.com/products/ssd/essd.go
设备 进程 流程
客户端 client 发起sync
  内核 物理网卡
服务端gw物理机 内核 物理网卡 bond1
    iptables
    ipvs
    虚拟网卡 vxnet
  flannel 转发,udp?
  gateway listen & accept
    协议解析
    路由查询
    子任务拆分执行
    backup request
    redirect
  内核 虚拟网卡 vxnet
服务端dbs物理机 内核 虚拟网卡 vxnet
  flannel 本地转发
  database listen & accept

服务进程(gw/dbs等)连接处理异常

场景:

业务请求大量超时,或存在明显的IP到IP的延时高或超时

表现:

服务端recv-q阻塞,数值长时间未变动或增加

可能的原因:

过载,超过处理速率

检查cpu是否占满

检查单核

检查单线程

检查k8s 的cpu是否达到limit

检查numa

检查是否存在pipeline串行

软件bug,连接未处理

解决手段:

过载则扩容,注意避免hash映射导致的集中

bug要修,紧急手段要具体分析

k8s组件导致异常连接

场景:

少量IP到IP之前,访问完全不通

服务端是k8s的非host网络

表现:

服务端连未绑定进程(线程id显示 - ),状态是ESTABLISHED,截图不准确(没找到其他图)

对应端口是kube-proxy或者galaxy在监听

原因:

galaxy/kubeproxy进程listen后,相关服务的pod重启过程中客户端尝试建立连接,将不会触发accept

处理手段:

有访问的情况下,可以通过tcpkill断掉指定连接,影响范围较小

无论有无访问,均可通过重启galaxy/kubeproxy(根据对应监听端口确认)的方式来进行恢复

自动断链抖动

dcc断链

dcc有默认断链时长,关键字close

rpc断链

rpc client/service均有断链时长

关键词为idle_time

内核断链

内核默认7200s断链(2h)

sysctl net.ipv4.tcp_keepalive_time

ivps断链

ipvs tcp 默认900s断链(15min)

新上集群调整为7200s(2h) ivpsadm -L –timeout conntrack断链

默认432000s断链(3day) sysctl net.netfilter.nf_conntrack_tcp_timeout_established

dns/路由异常

todo dns缺失

nslookup $dns dns同步缓慢

查看etcd cpu 路由缺失

todo,近期无路由缺失case 路由表过大 iptables -L

上述查询命令查询缓慢,会高频提示有锁 iptables-save | wc -l

检查表项目,通常是表项过多(1W~10W)

此时kubelet组件可能会注册iptables失败,但是仍然ready,导致访问失败

可以通过缩减表项、增加kubelet组件sync频率、或者切换到ipvs策略来解决

netstat netstat -nap | grep gateway | grep ESTAB

其中,-p会打印线程名;会导致开销增加。频繁执行时一般不加-p

注意,容器内外执行效果不同。目前监控只抓了host的 ss ss -nap | grep gateway | grep ESTAB

效率优于netstat,会打印fd。推荐

据说在老版本linux没有安装。但是目前现网设备都支持 tcpkill

伪装rst包以停连接,只能用于有请求的连接。若无请求,则联系开发使用特殊版本。对业务来说,能够感知连接关闭,可能会有微量失败

安装,建议在宿主机

yum install dsniff -y

使用netstat获取需要断链的信息,并聚合

执行,语法和tcpdump近似

tcpkill -i bond1 dst port 20000 and src host 1.1.1.1

会持续抓包断链,需要一定时间

业务可能会新建连接,因此不保证业务访问一定掉底

重新检查连接是否存在

iptables

拉取

iptables -L

等待拉取

iptables -L -w

nat表拉取

iptables -L -w -t nat

纯拉取,无锁

iptables-save
ipvsadm
yum install -y ipvsadm
ipvsadm-save

ipset list