批量读取记录
除了每次读取单条记录外,还可以在一个事务中从集群中读取多条记录。相关的客户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