【问题标题】:In etcd v3.0.x, how do I request all keys with a given prefix?在 etcd v3.0.x 中,如何请求具有给定前缀的所有键?
【发布时间】:2022-02-23 11:16:19
【问题描述】:

在 etcd 3.0.x 中,引入了一个新的 API,我只是在阅读它。在RangeRequest 对象中,我不清楚一件事。在description of the property range_end 中,它说:

如果 range_end 比给定键大一位, 然后范围请求获取带有前缀的所有键(给定键)。

这里是完整的文本,提供一些上下文:

// key is the first key for the range. If range_end is not given, the request only looks up key.
bytes key = 1;
// range_end is the upper bound on the requested range [key, range_end).
// If range_end is '\0', the range is all keys >= key.
// If the range_end is one bit larger than the given key,
// then the range requests get the all keys with the prefix (the given key).
// If both key and range_end are '\0', then range requests returns all keys.
bytes range_end = 2;

我的问题是:这是什么意思

如果 range_end 比给定键大一位

?这是否意味着range_endkey 长1 位?这是否意味着当解释为整数时它必须是key+1?如果是后者,使用哪种编码方式?

【问题讨论】:

    标签: etcd


    【解决方案1】:

    PR 解决了这种困惑。

    如果 range_end 是键加一(例如,“aa”+1 == “ab”、“a\xff”+1 == “b”), 然后范围请求获取所有以 key 为前缀的键。

    更新:

    var key = "/aaa"
    var range_end = "/aa" + String.fromCharCode("a".charCodeAt(2) + 1);
    

    【讨论】:

      【解决方案2】:

      key 的最后一个字节大一点。
      例如,如果key 是“09903x”,那么range_end 应该是“09903y”。
      发送到etcd服务器时只有字节流,所以要关心驱动的序列化,确定range_end的值。

      【讨论】:

        【解决方案3】:

        这里有一个很棒的 TypeScript 示例:https://github.com/mixer/etcd3/blob/7691f9bf227841e268c3aeeb7461ad71872df878/src/util.ts#L25

        使用 TextEncoder/TextDecoder 工作 js 示例:

        function endRangeForPrefix(value) {
            let textEncoder = new TextEncoder();
            let encodeValue = textEncoder.encode(value);
        
            for (let i = encodeValue.length - 1; i >= 0; i--) {
                if (encodeValue[i] < 0xff) {
                    encodeValue[i]++;
                    encodeValue = encodeValue.slice(0, i + 1);
        
                    let textDecoder = new TextDecoder();
                    let decode = textDecoder.decode(encodeValue);
                    return decode;
                }
            }
        
            return '';
        }
        

        【讨论】:

          【解决方案4】:

          我正在使用 python aioetcd3。我也遇到了同样的问题,不过在他的源码里找到了办法。

          aioetcd3/utils.py 第 14 行

          def increment_last_byte(byte_string):
              s = bytearray(to_bytes(byte_string))
              for i in range(len(s) - 1, -1, -1):
                  if s[i] < 0xff:
                      s[i] += 1
                      return bytes(s[:i+1])
              else:
                  return b'\x00'
          

          用法:

          await Client().delete([db_key, increment_last_byte(db_key)], prev_kv=True)
          

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2016-10-06
            • 1970-01-01
            • 2023-03-16
            • 1970-01-01
            • 2013-08-19
            相关资源
            最近更新 更多