types - 设置 Aerospike bin 中最小值的原子操作

标签 types lua user-defined-functions aerospike

我需要为 Aerospike 进行原子“设置最小值”操作,其中我给出一个 bin 名称和一个数字参数,然后设置并返回 bin 或参数的当前值(以较低者为准)。

以下 Lua UDF 应该可以工作

测试.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)

还有其他方法可以做到这一点吗?

最佳答案

在任何数据库中,用户定义函数的运行速度都会比 native 操作慢。这在 Aerospike 中没有什么不同,其中 Lua UDF 将具有更高的延迟,并且不会像 native 操作那样扩展。

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

我们可以利用有序列表来执行与上面的 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. 使用有序列表,将唯一值添加到列表中, 如果该值已经存在,则优雅地失败。该 list 应该 现在有一个或两个元素。
  2. 列表被修剪为仅包含排名最低的元素。
  3. 返回排名最低的元素(列表中应该只有一个)。

这三个操作在记录锁下以原子方式发生。

有关引用,请参阅 docs for the Python client .

关于types - 设置 Aerospike bin 中最小值的原子操作,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53184506/

相关文章:

c++ - 我如何清理我的 lua 状态堆栈?

lua - Lua 中的链表

javascript - 通过Apache Pig UDF读取javascript文件

scala - 将列和映射传递到 Scala UDF

rust - 预期类型参数,发现不透明类型

typescript - 如何理解类型 any、unknown、{} 之间以及它们与其他类型之间的关系?

php - 在 PHP 中指定类的对象类型的方法

string - 字符串中可能存在的字符的模式

C++/QT - 通过 QByteArray 将数据转换为不同的格式不同于读入结构

excel - 如何在运行时 VBA 显示 UDF 的工具提示?