後面的代碼引用自示例目錄【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);
}
清理資源
若記錄鍵是從堆上分配,應在使用後清理釋放。