在 Aerospike bin 中设置最小值的原子操作
Atomic operation to set minimum value in an Aerospike bin
我需要 Aerospike 的原子 'set minimum' 操作,我在其中给出一个 bin 名称和一个数字参数,以较低者为准,设置并返回 bin 或参数的当前值。
以下 Lua UDF 应该可以工作
test.lua
function set_min(rec, bin_name, value)
if aerospike:exists(rec) then
local min = rec[bin_name]
if min > value then
rec[bin_name] = value
aerospike:update(rec)
end
else
rec[bin_name] = value
aerospike:create(rec)
end
return rec[bin_name]
end
运行 参数 11, 9, 5, 7:
aql> execute test.set_min('minval', 11) on test.set-min where PK=2
+---------+
| set_min |
+---------+
| 11 |
+---------+
1 row in set (0.001 secs)
OK
aql> execute test.set_min('minval', 9) on test.set-min where PK=2
+---------+
| set_min |
+---------+
| 9 |
+---------+
1 row in set (0.001 secs)
OK
aql> execute test.set_min('minval', 5) on test.set-min where PK=2
+---------+
| set_min |
+---------+
| 5 |
+---------+
1 row in set (0.001 secs)
OK
aql> execute test.set_min('minval', 7) on test.set-min where PK=2
+---------+
| set_min |
+---------+
| 5 |
+---------+
1 row in set (0.000 secs)
还有其他方法吗?
在任何数据库中,用户定义的函数都会 运行 比本机操作慢。这在 Aerospike 中没有什么不同,其中 Lua UDF 将具有更高的延迟并且不会像本机操作那样扩展。
Aerospike 的 List and Map 数据类型具有广泛(且不断增长)的原子操作 API。这些操作可以组合成一个单一的多操作事务(使用 operate() 方法)。
我们可以利用有序列表来执行与上面的 UDF 相同的原子操作,其方式 运行s 更快并且扩展性更好。
set_min.py
from __future__ import print_function
import aerospike
from aerospike import exception as e
from aerospike_helpers.operations import list_operations as lh
import pprint
import sys
def set_min(bin_name, val):
list_policy = {
"list_order": aerospike.LIST_ORDERED,
"write_flags": (aerospike.LIST_WRITE_ADD_UNIQUE |
aerospike.LIST_WRITE_PARTIAL |
aerospike.LIST_WRITE_NO_FAIL)
}
ops = [
lh.list_append(bin_name, val, list_policy),
lh.list_remove_by_rank_range(bin_name, 0, aerospike.LIST_RETURN_NONE,
1, True),
lh.list_get_by_rank(bin_name, 0, aerospike.LIST_RETURN_VALUE)
]
return ops
config = {'hosts': [('172.16.39.132', 3000)]}
client = aerospike.client(config).connect()
pp = pprint.PrettyPrinter(indent=2)
key = ('test', 'set-min', 1)
key, meta, bins = client.operate(key, set_min('minval', 11))
pp.pprint(bins['minval'])
key, meta, bins = client.operate(key, set_min('minval', 9))
pp.pprint(bins['minval'])
key, meta, bins = client.operate(key, set_min('minval', 5))
pp.pprint(bins['minval'])
key, meta, bins = client.operate(key, set_min('minval', 7))
pp.pprint(bins['minval'])
client.close()
运行 参数 11, 9, 5, 7:
11
9
5
5
- 使用有序列表,将唯一值添加到列表中,
如果这个值已经存在,则优雅地失败。该清单应
现在有一个或两个元素。
- 列表被裁剪为仅包含排名最低的元素。
- 返回排名最低的元素(列表中应该只有一个)。
这三个操作在记录锁下自动发生。
我需要 Aerospike 的原子 'set minimum' 操作,我在其中给出一个 bin 名称和一个数字参数,以较低者为准,设置并返回 bin 或参数的当前值。
以下 Lua UDF 应该可以工作
test.lua
function set_min(rec, bin_name, value)
if aerospike:exists(rec) then
local min = rec[bin_name]
if min > value then
rec[bin_name] = value
aerospike:update(rec)
end
else
rec[bin_name] = value
aerospike:create(rec)
end
return rec[bin_name]
end
运行 参数 11, 9, 5, 7:
aql> execute test.set_min('minval', 11) on test.set-min where PK=2
+---------+
| set_min |
+---------+
| 11 |
+---------+
1 row in set (0.001 secs)
OK
aql> execute test.set_min('minval', 9) on test.set-min where PK=2
+---------+
| set_min |
+---------+
| 9 |
+---------+
1 row in set (0.001 secs)
OK
aql> execute test.set_min('minval', 5) on test.set-min where PK=2
+---------+
| set_min |
+---------+
| 5 |
+---------+
1 row in set (0.001 secs)
OK
aql> execute test.set_min('minval', 7) on test.set-min where PK=2
+---------+
| set_min |
+---------+
| 5 |
+---------+
1 row in set (0.000 secs)
还有其他方法吗?
在任何数据库中,用户定义的函数都会 运行 比本机操作慢。这在 Aerospike 中没有什么不同,其中 Lua UDF 将具有更高的延迟并且不会像本机操作那样扩展。
Aerospike 的 List and Map 数据类型具有广泛(且不断增长)的原子操作 API。这些操作可以组合成一个单一的多操作事务(使用 operate() 方法)。
我们可以利用有序列表来执行与上面的 UDF 相同的原子操作,其方式 运行s 更快并且扩展性更好。
set_min.py
from __future__ import print_function
import aerospike
from aerospike import exception as e
from aerospike_helpers.operations import list_operations as lh
import pprint
import sys
def set_min(bin_name, val):
list_policy = {
"list_order": aerospike.LIST_ORDERED,
"write_flags": (aerospike.LIST_WRITE_ADD_UNIQUE |
aerospike.LIST_WRITE_PARTIAL |
aerospike.LIST_WRITE_NO_FAIL)
}
ops = [
lh.list_append(bin_name, val, list_policy),
lh.list_remove_by_rank_range(bin_name, 0, aerospike.LIST_RETURN_NONE,
1, True),
lh.list_get_by_rank(bin_name, 0, aerospike.LIST_RETURN_VALUE)
]
return ops
config = {'hosts': [('172.16.39.132', 3000)]}
client = aerospike.client(config).connect()
pp = pprint.PrettyPrinter(indent=2)
key = ('test', 'set-min', 1)
key, meta, bins = client.operate(key, set_min('minval', 11))
pp.pprint(bins['minval'])
key, meta, bins = client.operate(key, set_min('minval', 9))
pp.pprint(bins['minval'])
key, meta, bins = client.operate(key, set_min('minval', 5))
pp.pprint(bins['minval'])
key, meta, bins = client.operate(key, set_min('minval', 7))
pp.pprint(bins['minval'])
client.close()
运行 参数 11, 9, 5, 7:
11
9
5
5
- 使用有序列表,将唯一值添加到列表中, 如果这个值已经存在,则优雅地失败。该清单应 现在有一个或两个元素。
- 列表被裁剪为仅包含排名最低的元素。
- 返回排名最低的元素(列表中应该只有一个)。
这三个操作在记录锁下自动发生。