BPF LRU_HASH_MAP 及 HASH_MAP 的使用异常

BPF 技术看起来还有很多不易察觉的缺陷。最近又踩了一个坑。记录下。

LRU_HASH_MAP 在实现的时候,出现了不符合预期的数据驱逐问题:设定一个 512 大小的LRU_HASH_MAP,很可能出现在40-50个key的时候,之前的key就被覆盖。在一段时间未更新时,重新更新也可能会出现异常。总结就是,执行了写入操作,很可能没有写入。这个问题在Elements incorrectly evicted from eBPF LRU hash map有较为详细的描述。

但是,笔者之所以使用LRU_HASH_MAP主要是期望保持整个程序的鲁棒性:期望可以一直写入key而不需对bpf map的状态进行维护。如果使用固定大小的HASH_MAP,当写入的key超过map的预设大小时,测试的demo会出现崩溃的现象。由于LRU_HASH_MAP的功能出现了不符合预期的情况,显然也就需要使用HASH_MAP来替代了。
笔者遇到的需要使用LRU_HASH_MAP的场景有两种:1. 作为配置项。用户态的代码向BPF MAP里写入配置,而后在BPF里使用。2. 作为数据中转。比如涉及多个hook点配合时,就需要使用BPF MAP来存储一些中间数据。对于场景1,可以直接使用HASH_MAP来替代,用户态添加一些检查的措施,定期批量对MAP进行数据清理以及数据写入即可。但是对于场景2,可能会麻烦很多:数据是随时产出的,用户态没有办法控制其产出的频率、周期。目前能想到的是设置一个较大的MAP(这个异常的触发是否和MAP的大小有关?),仍然使用LRU_HASH_MAP;或者设置一个较大的HASH_MAP,然后定时在用户态进行数据的清理。
以上。

Licensed under CC BY-NC-SA 4.0
Hello, World!
使用 Hugo 构建
主题 StackJimmy 设计