blog review 第十二期
看tag知内容
[toc]
数据库系统 · 事物并发控制 · Two-phase Lock Protocol
值得一看
模版元编程 hana
说实话,我已经放弃了,我看不懂
LaserDB
感觉所有大厂都在搞多租户
这个除了多租户,什么一致性啥都没有,有redis接口实现 和pika没啥差别,数据就是mapreduce导入
连数据接口都是len key len val len形式,感觉大家的 格式都差不多
用folly搭起来的。我们这边也是folly
多阶hash实现与分析
其实就是多层hash摞一块
这里有个简单实现https://github.com/zfengzhen/mem_hash
gRPC - Best Practices
与其说是grpc最佳实践,不如说是protobuf最佳实践
之前也说过一些最佳实践,这里又记录一点,有点分散。不过我的博客都是本地拿来搜的,所以还好,就不整理了
-
首先是风格约束,官方有实践了,就是文件名/接口大小写之类的
-
接口request/response要分开,别粘在一起
service BookService {
rpc CreateBook(Book) returns (Book); // don't do this
rpc ListBooks(ListBooksRequest) returns (ListBooksResponse); // this is OK
rpc GetBook(GetBookRequest) returns (Book); // this is also OK
rpc DeleteBook(DeleteBookRequest) returns (google.protobuf.Empty); // this is also OK
}
- 枚举
一般来说枚举字段默认值是0,但是依靠0来做默认,不是很好,可能掩盖问题,可以把枚举的0设置成ENUM_NAME_UNSPECIFIED之类的字段
enum Genre {
GENRE_UNSPECIFIED = 0;
GENRE_HORROR = 1;
GENRE_FANTASY = 2;
GENRE_ROMANCE = 3;
}
这个确实不知道,protobuf内置来一些公共类型,比如timestamp
import "google/protobuf/timestamp.proto";
message Book {
google.protobuf.Timestamp creation_time = 1;
}
- 版本兼容性
一般来说,添加个字段不会影响接口兼容性(不改字段的id)修改字段名字,删除字段也没什么影响
如果必须要引入重大改动呢?
不同的protobuf package做版本隔离
package app.kreya.v1;
- optional
这个字段修饰在protobuf3中被删掉了,实现上类似功能大多用猥琐的oneof
考虑一个int32 你无法区分设置了,因为默认值就是0,也有可能是你赋值的0,protobuf提供了封装类型
import "google/protobuf/wrappers.proto";
message Foo {
google.protobuf.Int32Value bar = 1;
}
protobuf 3.15版本,又把optional给加回来了。真有你的啊google
复杂类型除了字段一一对应外,也可以用google.protobuf.Any或者google.protobuf.Struct一股脑拿过来,内部自己解。风险自负
EVCache
https://netflixtechblog.com/announcing-evcache-distributed-in-memory-datastore-for-cloud-c26a698c27f7
https://netflixtechblog.com/ephemeral-volatile-caching-in-the-cloud-8eba7b124589
https://netflixtechblog.medium.com/cache-warming-leveraging-ebs-for-moving-petabytes-of-data-adcf7a4a78c3
用java封装了一层memcache上层弄一个hash环
是各种数据的cache,比如电影简介预告片之类的
最新博客说netflix的cache规模,18000台机器,14PB数据,这样用cache只能说非常有钱
netflix用cache更像是拿cache当只读数据库,所以冷数据变热很重要,热点数据要增强可读性,数据导入也很重要,越快越好
引入几个组件
Cache Warmer,两个功能
-
热点数据扩节点 立刻把数据加载到内存变热
-
当前节点数据过期,导入新数据,立刻变热
满足这两个功能的前提下,降低对客户端延迟的影响 (CPU/网络流量等等),降低内存使用,尽可能快的加载可用
亚马逊ebs来实现数据快速扩,EBS可以理解成一个移动硬盘,而且支持多机读一个,对于只要可读性的场景,再好不过,不需要复制一份数据
整体流程,EBS是中介,cache warmer controler负责把数据写到ebs, 另一侧有个cache populator吧ebs读到
涉及到的问题
- EBS的权限问题,读写管理,在迁移期间需要控制,这个是由中间增额controller来决定的
- 怎么dump数据?memcache本身有crawler API,cachemover直接调用就行了
- 要保证cachemover的可用性,被OOM干掉要能感知到
具体来说这个cachemover就是一个典型的生产消费模型了
文章里有具体的设计
除此之外,还尽可能 的零拷贝,以及支持快照,方便OOM重启后继续工作
cachemover的代码我没看,我感觉整体亮点都在EBS上了,像是EBS的软文广告
cachelib
facebook出了一个cachelib
视频 https://www.youtube.com/watch?v=wp_X-Zg9WEo
视频ppt https://www.usenix.org/sites/default/files/conference/protected-files/osdi20_slides_berg.pdf
论文 https://www.usenix.org/system/files/osdi20-berg.pdf
文档https://cachelib.org
之前太多的cache系统(discache kvell还有内部维护的各种memcache之类的)维护起来非常痛苦
cachelib又是一个one for all的库
提出的几个重要观点
key大小很重要,局部性/高效访问 memcache 56 memc3 40 你要是大于100就性价比不高了
每个object的key要小且能满足索引上T数据
这个api有点像memcache这几年出的硬盘扩展模式Extstore,部分内存部分固态
- 内存DRAM 链式hashtable 31B
- 固态FLASH 根据大小分区 小对象(SOC) 上亿 大对象(LOC) 百万 2k大小分界点
- 大对象要有内存索引,额外11.5B
- 小对象4K对齐,可能额外多1B
- 在flash中对象,会有策略控制,尽量避免写
- 尽量顺序写,降低写放大
除此之外,还要有热启动(cache持久化)多种数据类型存储(不需要序列化开销)等等功能
https://zhuanlan.zhihu.com/p/430451374 这篇文章列举的非常细致,总结了论文内容,我这里就不多啰嗦了,去看代码了
kangroo
https://github.com/saramcallister/Kangaroo
https://github.com/saramcallister/CacheLib-1/tree/artifact-eval-kangaroo-upstream
https://github.com/facebook/CacheLib/pull/50/files
https://dl.acm.org/doi/pdf/10.1145/3477132.3483568
https://www.micahlerner.com/2021/12/11/kangaroo-caching-billions-of-tiny-objects-on-flash.html
TODO
https://github.com/couchbase/couchstore/tree/master/src
https://github.com/couchbase/kv_engine/pulls
https://github.com/couchbase/phosphor
https://github.com/arkingc/note/
项目文档可以用这个https://github.com/aksakalli/jekyll-doc-theme