缓存字典布局
cached 字典布局类型会将字典存储在具有固定数量单元格的缓存中。
这些单元格包含经常使用的元素。
字典键的类型是 UInt64。
在查找字典时,首先会搜索缓存。对于每个数据块,所有在缓存中未找到或已过期的键会通过 SELECT attrs... FROM db.table WHERE id IN (k1, k2, ...) 向源请求。接收到的数据随后会写入缓存。
如果在字典中未找到键,则会创建更新缓存任务并将其加入更新队列。可以通过 max_update_queue_size、update_queue_push_timeout_milliseconds、query_wait_timeout_milliseconds、max_threads_for_updates 这些设置控制更新队列属性。
对于缓存字典,可以设置缓存中数据的过期 lifetime。如果自单元格中数据加载以来已经过去的时间超过 lifetime,则不会使用该单元格的值,并且该键会变为过期状态。下次需要使用该键时会重新请求。可以通过设置 allow_read_expired_keys 配置此行为。
这是所有存储字典方式中效率最低的一种。缓存速度强烈依赖于正确的设置和使用场景。仅当命中率足够高时(建议 99% 及以上),缓存类型的字典才会有良好表现。可以在 system.dictionaries 表中查看平均命中率。
如果将设置 allow_read_expired_keys 设为 1(默认值为 0),则字典可以支持异步更新。如果客户端请求了一组键,这些键都在缓存中,但其中一些已过期,则字典会向客户端返回这些过期键,并从源端异步请求它们。
为了提升缓存性能,请在子查询中使用 LIMIT,并在外部调用字典函数。
支持所有类型的源。
设置示例:
- DDL
- Configuration file
请设置足够大的缓存大小。需要通过试验选择单元格数量:
- 设定一个值。
- 运行查询,直到缓存完全填满。
- 使用
system.dictionaries表评估内存消耗。 - 增加或减少单元格数量,直到达到所需的内存消耗。
不推荐使用 ClickHouse 作为此布局的源。字典查找需要随机点读,这并不是 ClickHouse 所优化的访问模式。