26 Feb 2024 | computer architecture, contest
修订历史
- 2024.02.26 创建笔记
- 2024.03.15 增加 1BRC
- 2024.11.28 补充百万队列笔记
赛题:高 qps 的 dubbo agent 实现
wrk 是一款针对 http 协议的基准测试工具, 可以使用 Lua 脚本进行复杂测试
grep -- -v file # 在 "file" 中 grep 字符串 "-v"
题目:在单机环境下,实现带有持久化的消息队列引擎。
实现以下接口供生产者进程调用:
实现以下接口供消费者进程调用:
topic和queue是多对多关系。消费者和queue是一一对应关系。发送者可以选择发送到Topic,也可以选择直接发送到Queue。topic和queue的数目大约是100个(其中queue的数目与消费者线程数相等)。
消息要保证发送者内顺序一致。顺序只针对单个topic或者queue,不同topic,不同queue,topic与queue之间都不用考虑顺序。
每条消息大小不会超过256K,总共4kw条。消息由头部(headers)、属性(properties)、主体(body)三个部分组成,其中头部和属性均为KeyValue结构,消息主体为byte[]数组。header与properties中key和value都不会插入null或空值
评测方式:
详细:https://github.com/RapidsBlink/OpenMessageShaping/blob/master/README.md
dirty_ratio和dirty_background_ratio是Linux系统中与磁盘缓存和脏页(dirty pages)相关的参数。
dirty_ratio:该参数定义了系统内存中脏页所占的最大比例。当脏页的比例达到或超过dirty_ratio时,系统会开始触发脏页的写入操作,将其阻塞写入磁盘。该参数的单位是百分比,默认值为20。
dirty_background_ratio:该参数定义了系统内存中脏页所占的比例,达到或超过该比例时,后台进程开始异步写入脏页到磁盘。该参数的单位也是百分比,默认值为10。
综上所述,需要将4kw条数据进行压缩。理论上压缩后的总大小小于物理内存的20%,那磁盘IO对于写线程总是异步的。
此外,每次压缩一条数据,效率比较低。可以考虑设置压缩缓存区
文件落盘减少锁冲突。
方案:每个名字一个文件夹,例如Topic0或Queue0一个文件夹;在文件夹下面,每个文件是每个线程的名字(因为一个线程绑定一个Producer)
多个消费者都订阅同一个topic,需要避免重复读文件,避免重复解码构造并析构消息。
方案:考虑把消费者pull改成push架构:n个文件n个线程来消费文件,分发消息到订阅的消费者队列中;同时若topic文件没被订阅,可以忽略该文件。
Linux 内核会将它最近访问过的文件页面缓存在内存中一段时间,这个文件缓存被称为 PageCache。
题目:进行数据库(从空开始)的主从增量同步,输入为10G顺序append的日志文件(只能单线程顺序读取1次,模拟真实流式处理场景)。日志文件中包含insert key(带有全部属性)/delete key/update property(单个)/update key这四种类型的数据变化操作(通过I/D/U以及其他日志中的字段标识)。其中,10G数据在server端,最后的查询结果需要落盘在client端,server和client是两台配置相同的16逻辑cpu核数的云虚拟机。
详细:https://github.com/RapidsBlink/IncrementalSyncShaping/blob/master/README.md
https://github.com/gunnarmorling/1brc
题目:10 亿行的文件中,每一行记录的是一个气象站的温度值。气象站和温度分号分隔,温度值只会保留一位小数。解析这个文件,计算出每个气象站的最小、最大和平均温度。按照字典序的格式输出。
The performance difference between a warm and a hot pagecache is quite extreme. Run
echo 3 > /proc/sys/vm/drop_caches
to drop your pagecache, then run the program twice in a row. It’s not uncommon for the second run to be well over twice as fast.
#if 0 // self-compiling code: just 'chmod +x' this file and run it directly!
c++ -std=c++11 -Wall -Wextra -pedantic -Werror -g -O3 -march=native $0 || exit 1
exec ./a.out $*
#endif
... // source code