如果设置了policy_batch_apply.POLICY_KEY_SEND,为什么batch_apply对于多个密钥会失败?

问题描述 投票:0回答:1

我想在一个批处理中创建/更新一组记录,以原子方式处理可能的更新操作。我有一组密钥以及每个密钥的相应数据。我还注册了一个 UDF,用于检查记录是否已存在。如果是,它会根据旧记录数据和新记录数据执行额外的工作。然后更新记录。

根据文档和示例,batch_apply 允许将功能应用于提供的键集。但是,该示例对所有键使用相同的数据。我需要特定密钥的特定数据。

我尝试拨打以下电话:

data = { k1: d1, k2: d2, k3: d3}
keys = list(data.keys())
asclient.batch_apply(keys, "my_module", "my_function", data)

其中 my_function 定义为:

function my_function(rec, args)
    if aerospike:exists(rec) then
        pk = record.key(rec)
        data = args[pk]
        -- update record data using new data and old data
        some code for data manipulation
        -- update record
        aerospike:update(rec)
    else
        -- no record stored yet, store using data for the key
        pk = record.key(rec) -- returns nil as record doesn't exist
        data = args[pk] -- fails
        aerospike:create(rec)
    end
end

然后我尝试通过policy请求密钥:

data = { k1: d1, k2: d2, k3: d3}
keys = list(data.keys())
asclient.batch_apply(keys, "my_module", "my_function", data, policy_batch_apply={'key': aerospike.POLICY_KEY_SEND})

从记录中获取密钥:

function my_function(rec, args)
    if aerospike:exists(rec) then
    ...
    else
        pk = record.key(rec) -- returns nil as record doesn't exist
        -- create empty record to get the key stored thanks to policy
        aerospike:create(rec)
        -- finally, key is there
        pk = record.key(rec)
        data = args[pk]
        -- set data to record
        ...
        -- update empty record with actual data
        aerospike:update(rec)
    end
end

这有效,但前提是 keys 仅包含 1 个键。如果我输入 2,我会在 AS 日志中看到以下警告

Oct 01 2024 09:19:37 GMT: WARNING (batch): (batch.c:1015) batch must not repeat key
Oct 01 2024 09:19:37 GMT: WARNING (batch): (batch.c:1188) Batch keys mismatch. Expected 2 Received 1

my_function 仅针对第一个键调用。我查看了 code ,似乎如果 aerospike.POLICY_KEY_SEND 则隐式设置了 REPEAT 标志,但这在任何地方都没有描述。

aerospike aerospike-ce
1个回答
0
投票

我可以从Java客户端的角度解释一些基本概念。希望这对您的问题有所帮助。其他客户端应该有等效的 API。另外,假设最新的服务器版本。

1 - 关于 sendKey = true - 它检查哈希冲突。 Aerospike 通过使用用户提供的密钥、集名称(如果使用集)和密钥类型(推断)计算出的 20 字节 RIPEMD-160 哈希来存储/定位记录。此外,在写入期间,您可以将此用户密钥与具有 sendKey=true 策略的记录一起存储。 当您使用 sendKey=true 策略更新或读取记录时,该记录通过摘要进行定位,但存储的用户密钥也会根据您在此事务中的密钥进行双重检查 - 从而检测可能的哈希冲突。 大多数用户不会进行此检查,因为概率接近于零。 但是,如果您使用 sendKey=true 读取或更新,但最初并未使用 sendKey = true 创建记录,则检查将失败,因为记录中没有存储用户密钥。

2 - 关于批量更新每个记录都有自己的数据 - 也可以单独更新每个记录。但是,如果您想使用 UDF 进行批量写入,则必须使用(在 Java 中)操作(BatchPolicy 策略,List < BatchRecord > 记录) api - 与您的客户端等效。 https://javadoc.io/doc/com.aerospike/aerospike-client-jdk8/latest/index.html。现在,BatchUDF 扩展了 BatchRecord,让您可以单独为每条记录设置数据。 Aerospike Java 客户端代码位于公共存储库中 - 此处的链接作为 BatchUDF 的测试示例,可能会有所帮助。 https://github.com/aerospike/aerospike-client-java/blob/master/test/src/com/aerospike/test/sync/basic/TestUDF.java#L256

© www.soinside.com 2019 - 2024. All rights reserved.