Redis 中的散列标签

由于作者水平有限,失误在所难免,如有任何意见或建议,请不吝指正。

Redis Cluster 中有一个称为散列标签的概念,可用于强制将某些键存储在同一个散列槽中。Redis Cluster 不像 Redis 的独立版本那样支持多数据库。它只支持数据库 0;不允许使用 SELECT 命令。 Redis Cluster 实现了非分布式 Redis 版本中可用的所有单键命令。执行复杂的多键操作(如集合并集和交集)的命令要求操作中涉及的所有键散列到同一个槽。

哈希标签是一种确保在同一个哈希槽中分配多个键的方法。 这是为了在 Redis 集群中实现多键操作。 为了实现哈希标签,键的哈希槽在某些条件下以稍微不同的方式计算。简单来说,如果键包含 {...} 模式,则仅对 {} 之间的子字符串进行哈希。 但是,由于 {} 可能多次出现,因此算法由以下更加详细的规则指定:

那么,不是对整个键进行哈希,而是只哈希第一次出现的 { 和接下来的第一次出现的 } 之间的内容。下面是一些例子:

以下是 HASH_SLOT 函数的C语言版本:

unsigned int HASH_SLOT(char *key, int keylen) {
    int s, e; /* start-end indexes of { and } */

    /* Search the first occurrence of '{'. */
    for (s = 0; s < keylen; s++)
        if (key[s] == '{') break;

    /* No '{' ? Hash the whole key. This is the base case. */
    if (s == keylen) return crc16(key,keylen) & 16383;

    /* '{' found? Check if we have the corresponding '}'. */
    for (e = s+1; e < keylen; e++)
        if (key[e] == '}') break;

    /* No '}' or nothing between {} ? Hash the whole key. */
    if (e == keylen || e == s+1) return crc16(key,keylen) & 16383;

    /* If we are here there is both a { and a } on its right. Hash
     * what is in the middle between { and }. */
    return crc16(key+s+1,e-s-1) & 16383;
}

参考资料: