我有 Aerospike 的用例,其中有多个记录,例如:
+--------+---------+
| PK | signal |
+--------+---------+
| 123451 | 1 |
| 102221 | 1.0816 |
+--------+---------+
我的服务 A 在约 1000 Vms 的 VM 队列上运行,每 3 分钟读取一次此信号值。 现在,该信号值还需要根据服务 A 范围内的其他现实世界值 (x...y) 每 3 分钟更新一次。它可以每 3 分钟上升或下降,也可以每 24 小时重置一次。 此外,所有 1000 个虚拟机都需要同时看到相同的更新信号值。
现在理想的方法可能是运行一个单独的服务(服务 B),每 3 分钟更新一次此信号。但动态值很难在任何其他服务中重新创建,并且不容易导出。
因此,要在服务 A 中执行此操作,我可以在每个虚拟机上遵循 CAS(检查和设置)模式 我有一个调度程序每 3 分钟间隔执行一次同步到纪元的操作:
现在这是低效的,因为在最好的情况下,所有 1000 个服务 A 虚拟机都将向 aerospike 写回相同的值,范围到我可能遇到的最坏情况
考虑使用写入策略生成来实现此目的:
看起来很笨拙,所以尝试了这样的UDF:
function updateSignal(rec, binName, someParamX, someParamY, hyperParameter, resetFlag)
if aerospike:exists(rec) then
local currentSignal = rec[binName]
local geneneration = record.gen(rec)
if (someParamX > someParamY) then
local multiplier = someFunction()
local updatedSignal = currentSignal * multiplier
rec[binName] = updatedSignal
else
rec[binName] = 1
end
aerospike:update(rec)
else
aerospike:create(rec)
rec[binName] = 1
aerospike:update(rec)
end
return rec[binName] -- Return the updated value
end
问题是,在 UDF 上下文中,如果我不最初将 write gen 传递给 UDF,我实际上没有任何 write gen 检查能力。
此外,如果我将写入生成作为 UDF 调用的一部分传递,如果写入由于生成检查(冲突)而失败,我还需要返回信号的当前值。 因为如果记录是从其他地方更新的,那么一旦在 udf 上下文中我就不会收到更新的信号。 (这会发生吗?读某处udfs锁定记录?是读锁/写锁吗?)
有什么办法解决这个问题吗?我是不是错过了什么?
记录 UDF 将在持有记录锁的同时完全运行。因此,在读取然后更新记录的 UDF 内,您不能让另一个 VM 更改记录。希望这会有所帮助(我可能错过了您特定用例的一些微妙之处)。