原子操作以设置Aerospike垃圾箱中的最小值

时间:2018-11-07 06:25:12

标签: types lua user-defined-functions aerospike

我需要为Aerospike进行原子性的“最小设置”操作,在其中给出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)

还有另一种方法吗?

1 个答案:

答案 0 :(得分:3)

在任何数据库中,用户定义函数的运行速度都将比本地操作慢。这与Aerospike一样,Lua UDF的等待时间更长,并且无法像本机操作一样扩展。

Aerospike的ListMap数据类型具有原子操作的广泛(并且正在不断增长)的API。这些操作可以组合为一个多操作事务(使用operate()方法)。

我们可以利用有序List来执行与上面的UDF相同的原子操作,以更快的速度运行和更好的扩展。

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
  1. 使用有序列表,将唯一值添加到列表中, 如果此值已存在,则正常失败。该清单应 现在有一个或两个元素。
  2. 修剪列表以仅保留排名最低的元素。
  3. 返回排名最低的元素(列表中只能是一个)。

这三个操作在记录锁定下自动进行。

有关参考,请参见docs for the Python client