Aerospike C客户端手册———键-值存储—批量读取记录

时间:2021-04-17 08:43:29

批量读取记录

除了每次读取单条记录外,还可以在一个事务中从集群中读取多条记录。相关的客户Aerospike C客户端API调用是:

  • aerospike_batch_get() — 返回所需记录所有bin数据。
  • aerospike_batch_exists() — 返回所需记录元数据(生存时间, 分代编号)。

后面的代码引用自示例目录【examples/basic_examples/get】,由Aerospike C客户端安装包自带。

请先阅读【创建连接】章节内容,理解如何建立与集群的连接。

初始化批量请求

在执行批量调用前,首先初始化一个as_batch对象。下面的示例代码,初始化了一个要读取1000条记录的as_batch对象。

as_batch batch;
as_batch_inita(&batch, 1000);

初始化需读取记录的键

一旦as_batch对象初始化过,应设置需要读取记录们的键:

for (uint32_t i = 0; i < 1000; i++) {
as_key_init_int64(as_batch_keyat(&batch, i), "test", "demoset", (int64_t)i);
}

上面的调用,使用as_batch_keyat()函数设置了1000个键。在这里,键的数据类型是整型(integer),范围从0到1000。也可以使用不同数据类型的键,比如:字符串(string)。这些键用于读取记录的存储位置:namespace名称为"test"、set名称为“test-set”。

批量读取记录的键必须属于同一个namespace。

从数据库中读取记录

现在已经准备好执行读取记录的调用。

if (aerospike_batch_get(&as, &err, NULL, &batch, batch_read_cb, NULL) 
!= AEROSPIKE_OK) {
LOG("aerospike_batch_get() returned %d - %s", err.code, err.message);
cleanup(&as);
exit(-1);
}

在Aerospike C客户端内部,此调用按最佳处理请求的服务器节点来分组记录键,并为集群中这些节点每个启动一个批量任务。有6个(NUM_BATCH_THREADS)批量工作线程处理所有节点上的全部批量任务。若集群中有多于6个节点,理想状态下是增加默认线程数以让全部节点并行处理。

处理结果集

上面的aerospike_batch_get()函数示例使用回调函数batch_read_cb做为参数。回调函数具有如下型构:

bool (* aerospike_batch_read_callback)(const as_batch_read * results, uint32_t n, void * udata);

此回调函数将在所有节点返回全部记录后被调用,按照记录键被递交的顺序。

应用可遍历as_batch_read的结果列表并处理每一个记录。结果记录及数值只可见于回调函数作用域,若需要传递出回调函数作用域以外,必须显式地拷贝。

bool
batch_read_cb(const as_batch_read* results, uint32_t n, void* udata)
{

uint32_t n_found = 0;

for (uint32_t i = 0; i < n; i++) {
LOG("index %u, key %" PRId64 ":", i,
as_integer_getorelse((as_integer*)results[i].key->valuep, -1));

if (results[i].result == AEROSPIKE_OK) {
LOG(" AEROSPIKE_OK");
n_found++;
}
else if (results[i].result == AEROSPIKE_ERR_RECORD_NOT_FOUND) {
// The transaction succeeded but the record doesn't exist.
LOG(" AEROSPIKE_ERR_RECORD_NOT_FOUND");
}
else {
// The transaction didn't succeed.
LOG(" error %d", results[i].result);
}
}

return true;
}

若想在每次回调传递一个全局对象出来,请在调用aerospike_batch_get()时提供一个userdata类型的参数。

读取记录元数据

做为读取整条记录数据的替代,可以使用一个等价调用,但只返回记录的元数据(比如:生存时间、分代编号)。应用只想找出记录是否存在而不想承担实际读取数据成本时,可优先使用此调用。

if (aerospike_batch_exists(&as, &err, NULL, &batch, batch_read_cb, NULL) 
!= AEROSPIKE_OK) {
LOG("aerospike_batch_exists() returned %d - %s", err.code, err.message);
cleanup(&as);
exit(-1);
}

清理资源

若记录键是从堆上分配,应在使用后清理释放。


原文链接: http://www.aerospike.com/docs/client/c/usage/kvs/batch.html译       者: 歪脖大肚子Q