探索Aerospike:一款具備超讀寫能力、低延遲和高吞吐量的NoSQL數(shù)據(jù)庫

2024-12-17 14:25 更新

今天 V 哥要介紹一這款,超讀寫能力、低延遲和高吞吐量而聞名的 NoSQL 數(shù)據(jù)庫,它就是Aerospike。

1、先來了解一下Aerospike

Aerospike支持T級別的大數(shù)據(jù)存儲,并且能夠處理高并發(fā)的數(shù)據(jù)訪問,讀寫操作達到微妙級別,99%的響應可以在1毫秒內完成 。Aerospike 的架構設計允許它直接訪問SSD的原始塊,優(yōu)化了數(shù)據(jù)的讀取速度,同時支持二級索引和客戶端聚合,提供了類似SQL的查詢語言(AQL),這使得它在某些方面比其他NoSQL數(shù)據(jù)庫更具優(yōu)勢。

Aerospike 的應用場景主要集中在對容量要求較大且QPS相對較低的場景,例如互聯(lián)網(wǎng)廣告行業(yè)。在個性化推薦廣告應用中,Aerospike 可以存儲推薦引擎的結果,供廣告投放引擎實時獲取 。此外,Aerospike 也適用于實時競價廣告應用,其中用戶畫像數(shù)據(jù)存儲在Aerospike中,以支持DSP(需求方平臺)進行實時競價。

Aerospike 與 Redis相比,具有多線程處理能力,支持自動分片,并且可以動態(tài)增加數(shù)據(jù)卷和吞吐量,而無需停機。Aerospike 支持數(shù)據(jù)在內存中存儲索引,在HDD、SSD中保存數(shù)據(jù),也可以在內存中存儲全部數(shù)據(jù),這提供了更多的靈活性。

Aerospike 的架構分為三個層次:Client層、Distribution層和Data層。Client層是智能客戶端,支持多種編程語言,能夠感知數(shù)據(jù)存儲位置的變化。Distribution層負責數(shù)據(jù)的平衡分布、備份、容錯和同步。Data層負責數(shù)據(jù)存儲,采用弱語法的key-value數(shù)據(jù)庫模式,支持主索引和二級索引。

在多站點集群方面,Aerospike 支持跨多個數(shù)據(jù)中心的部署,具備機架感知和強大的即時數(shù)據(jù)一致性功能。它能夠自動維護集群狀態(tài)和數(shù)據(jù)存儲位置信息,快速克服各種故障,如節(jié)點丟失或數(shù)據(jù)中心故障 。Aerospike 的多站點集群可以配置為最多兩個數(shù)據(jù)中心維護兩個數(shù)據(jù)副本,或至少三個數(shù)據(jù)中心維護三個數(shù)據(jù)副本,從而提高可用性和故障轉移的自動化程度。

Aerospike 的數(shù)據(jù)模型包括Namespaces、Sets和Records,其中Namespaces是數(shù)據(jù)存儲的最高層級,Sets是邏輯分區(qū),Records包含key、Bins和Metadata。Aerospike 支持靈活的數(shù)據(jù)模式,并且支持滿足ACID特性的事務。

2、Aerospike 輕松上手

下面是Aerospike的入門教程,包括詳細的操作步驟示例。

下載安裝 Aerospike

Aerospike數(shù)據(jù)庫的下載和安裝過程可以根據(jù)不同操作系統(tǒng)進行。以下是針對Linux和Ubuntu系統(tǒng)的安裝指南:

Linux系統(tǒng)安裝Aerospike:

  1. 下載Aerospike軟件包:從Aerospike的官方網(wǎng)站下載適合您Linux發(fā)行版的安裝包,包括.rpm.deb格式 (網(wǎng)址敏感,自行在度娘搜索)。
  2. 提取軟件包內容:下載后,使用tar命令提取軟件包內容。
  3. 安裝Aerospike服務器和工具:進入包含安裝文件的目錄,運行sudo ./asinstall腳本來安裝服務器和命令行工具 aerospike-tools 。

驗證并測試一下

在Linux系統(tǒng)下驗證Aerospike是否安裝成功,您可以按照以下步驟進行:

  1. 檢查服務狀態(tài):使用systemctl命令來檢查Aerospike服務的狀態(tài)。

systemctl status aerospike

如果服務正在運行,您應該會看到active (running)的狀態(tài)信息。

  1. 列出已安裝的Aerospike包:使用包管理器列出已安裝的Aerospike軟件包。

  • 對于基于RPM的系統(tǒng)(如CentOS),使用yumrpm

yum list installed | grep aerospike

或者

rpm -qa | grep aerospike

  • 對于基于Deb的系統(tǒng)(如Ubuntu),使用dpkg

dpkg -l | grep aerospike

  1. 使用asinfo工具asinfo是Aerospike提供的一個命令行工具,可以用來獲取服務器狀態(tài)和統(tǒng)計信息。

asinfo -v STATUS

如果返回OK,則表示服務正在運行。

  1. 使用asadm工具asadm是另一個Aerospike的管理工具,可以用來執(zhí)行各種管理任務。

asadm

進入asadm之后,您可以使用它來檢查集群狀態(tài)或執(zhí)行其他命令。

  1. 檢查日志文件:查看Aerospike的日志文件,確認是否有錯誤信息或啟動日志。

cat /var/log/aerospike/aerospike.log

  1. 嘗試連接到Aerospike實例:使用Aerospike客戶端連接到服務器,嘗試執(zhí)行一些基本操作,如鍵值對的讀寫。

在Java項目中添加Aerospike依賴,打開pom.xml文件,并添加以下依賴代碼:

<dependencies>
    <!-- 其他依賴 -->


    <!-- Aerospike client dependency -->
    <dependency>
        <groupId>com.aerospike</groupId>
        <artifactId>aerospike-client</artifactId>
        <version>5.0.0</version> <!-- 請使用適合您項目的最新版本 -->
    </dependency>


    <!-- 其他依賴 -->
</dependencies>

來一段測試代碼使用一下:

   // 示例Java代碼片段
   import com.aerospike.client.AerospikeClient;
   import com.aerospike.client.Host;
   import com.aerospike.client.Info;


   // 創(chuàng)建客戶端實例
   AerospikeClient client = new AerospikeClient(new Host("192.168.1.100", 3000));


   // 檢查節(jié)點信息
   Node[] nodes = client.getNodes();
   for (Node node : nodes) {
       System.out.println(Info.request(node, "node"));
   }


   // 關閉客戶端連接
   client.close();

如果以上步驟都順利完成,并且沒有發(fā)現(xiàn)錯誤信息,那么可以認為Aerospike已經(jīng)成功安裝并運行在你的Linux系統(tǒng)上,大功告成。

3、模擬廣告業(yè)務場景案例

好的,讓我們模擬一個廣告業(yè)務場景,其中我們需要存儲和檢索廣告點擊數(shù)據(jù)。我們將使用Java來實現(xiàn)這個案例。

場景描述

假設我們有一個在線廣告系統(tǒng),需要記錄用戶的每次廣告點擊。每條點擊記錄包括以下信息:

  • 用戶ID(user_id
  • 廣告ID(ad_id
  • 點擊時間(click_time

我們將使用Aerospike來存儲這些點擊數(shù)據(jù),并能夠查詢特定用戶的點擊記錄。

步驟1:初始化Aerospike客戶端

首先,我們需要初始化Aerospike客戶端。

import com.aerospike.client.AerospikeClient;
import com.aerospike.client.Host;
import com.aerospike.client.Info;
import com.aerospike.client.Key;
import com.aerospike.client.Bin;
import com.aerospike.client.policy.ClientPolicy;
import com.aerospike.client.policy.WritePolicy;


public class AdClickSimulator {


    static {
        // 初始化Aerospike客戶端
        Host[] hosts = new Host[]{new Host("192.168.1.100", 3000)};
        ClientPolicy policy = new ClientPolicy();
        AerospikeClient client = new AerospikeClient(policy, hosts);
    }


    // 其他方法將在這里定義
}

步驟2:定義寫入點擊數(shù)據(jù)的方法

接下來,我們定義一個方法來模擬寫入點擊數(shù)據(jù)。

import com.aerospike.client.WritePolicy;
import java.util.Date;


public class AdClickSimulator {


    // ... 客戶端初始化代碼 ...


    public void simulateAdClick(String user_id, String ad_id, long click_time) {
        // 定義寫策略
        WritePolicy writePolicy = new WritePolicy();


        // 定義鍵
        Key key = new Key("ad_clicks", "user_" + user_id, ad_id);


        // 定義要寫入的bins
        Bin bin_user_id = new Bin("user_id", user_id);
        Bin bin_click_time = new Bin("click_time", click_time);


        // 寫入點擊數(shù)據(jù)
        client.put(writePolicy, key, bin_user_id, bin_click_time);
    }
}

步驟3:定義查詢點擊數(shù)據(jù)的方法

然后,我們定義一個方法來查詢特定用戶的點擊記錄。

import com.aerospike.client.Record;
import com.aerospike.client.query.Statement;


public class AdClickSimulator {


    // ... 客戶端初始化和寫入點擊數(shù)據(jù)的方法 ...


    public void queryUserClicks(String user_id) {
        // 定義查詢語句
        Statement statement = new Statement();
        statement.setNamespace("ad_clicks");
        statement.setName("user_" + user_id);


        // 執(zhí)行查詢
        com.aerospike.client.RecordSet rs = client.query(null, statement);


        // 打印查詢結果
        while (rs.next()) {
            Record record = rs.getRecord();
            System.out.println("Ad ID: " + record.getKey().getObject() + 
                ", User ID: " + record.getValue("user_id") +
                ", Click Time: " + new Date((Long)record.getValue("click_time")));
        }
        rs.close();
    }
}

步驟4:模擬廣告點擊

最后,我們編寫一個main方法來模擬廣告點擊并查詢結果。

public class AdClickSimulator {


    // ... 其他方法 ...


    public static void main(String[] args) {
        AdClickSimulator simulator = new AdClickSimulator();


        // 模擬用戶點擊廣告
        simulator.simulateAdClick("vin1", "ad1001", System.currentTimeMillis());
        simulator.simulateAdClick("vin1", "ad1002", System.currentTimeMillis() + 1000);
        simulator.simulateAdClick("vin2", "ad1003", System.currentTimeMillis() + 2000);


        // 查詢特定用戶的點擊記錄
        simulator.queryUserClicks("user1");
    }
}

注意哈,以上示例的前置條件是已經(jīng)配置了Aerospike服務器,并且ad_clicks這個namespaceset已經(jīng)存在。你只需要根據(jù)實際環(huán)境調整主機地址、端口和其他配置即可。

發(fā)現(xiàn)沒有,這個示例沒有處理異常和錯誤情況,下面是優(yōu)化過后的代碼如下。

以下是對之前示例的改進,增加了異常處理:

import com.aerospike.client.*;
import com.aerospike.client.policy.ClientPolicy;
import com.aerospike.client.policy.WritePolicy;


import java.util.Date;


public class AdClickSimulator {


    private AerospikeClient client;


    public AdClickSimulator() {
        // 初始化Aerospike客戶端
        Host[] hosts = new Host[]{new Host("192.168.1.100", 3000)};
        ClientPolicy policy = new ClientPolicy();
        this.client = new AerospikeClient(policy, hosts);
    }


    public void simulateAdClick(String user_id, String ad_id, long click_time) {
        try {
            // 定義寫策略
            WritePolicy writePolicy = new WritePolicy();


            // 定義鍵
            Key key = new Key("ad_clicks", "user_" + user_id, ad_id);


            // 定義要寫入的bins
            Bin bin_user_id = new Bin("user_id", user_id);
            Bin bin_click_time = new Bin("click_time", click_time);


            // 寫入點擊數(shù)據(jù)
            client.put(writePolicy, key, bin_user_id, bin_click_time);
            System.out.println("Click data written successfully for user: " + user_id);
        } catch (AerospikeException e) {
            System.err.println("Error writing click data: " + e.getMessage());
        }
    }


    public void queryUserClicks(String user_id) {
        try {
            // 定義查詢語句
            Statement statement = new Statement();
            statement.setNamespace("ad_clicks");
            statement.setName("user_" + user_id);


            // 執(zhí)行查詢
            RecordSet rs = client.query(null, statement);


            // 打印查詢結果
            while (rs.next()) {
                Record record = rs.getRecord();
                System.out.println("Ad ID: " + record.getKey().getObject() +
                        ", User ID: " + record.getValue("user_id") +
                        ", Click Time: " + new Date((Long) record.getValue("click_time")));
            }
            rs.close();
        } catch (AerospikeException e) {
            System.err.println("Error querying user clicks: " + e.getMessage());
        } catch (Exception e) {
            System.err.println("An unexpected error occurred: " + e.getMessage());
        }
    }


    public static void main(String[] args) {
        AdClickSimulator simulator = new AdClickSimulator();


        try {
            // 模擬用戶點擊廣告
            simulator.simulateAdClick("vin1", "ad1001", System.currentTimeMillis());
            simulator.simulateAdClick("vin1", "ad1002", System.currentTimeMillis() + 1000);
            simulator.simulateAdClick("vin2", "ad1003", System.currentTimeMillis() + 2000);


            // 查詢特定用戶的點擊記錄
            simulator.queryUserClicks("user1");
        } catch (Exception e) {
            System.err.println("An unexpected error occurred in the main simulation: " + e.getMessage());
        } finally {
            // 關閉客戶端連接
            if (simulator.client != null) {
                simulator.client.close();
            }
        }
    }
}

異常處理說明:

  1. 寫入點擊數(shù)據(jù) (simulateAdClick): 我們捕獲了AerospikeException,這是Aerospike客戶端用來表示與服務器通信時發(fā)生錯誤的異常。

  1. 查詢點擊數(shù)據(jù) (queryUserClicks): 同樣捕獲了AerospikeException。此外,我們還捕獲了一個通用的Exception來處理可能發(fā)生的任何其他異常。

  1. 主方法 (main): 在這里,我們捕獲了可能在模擬過程中發(fā)生的任何異常,并在finally塊中確保無論發(fā)生什么異常,客戶端連接都會被關閉。

4、最后

在選擇Aerospike時,需要考慮其性能、數(shù)據(jù)存儲、持久化、數(shù)據(jù)同步、數(shù)據(jù)分片和集群管理等方面與Redis和Memcached等其他解決方案的對比。Aerospike 的高性能讀寫能力、自動集群管理和監(jiān)控功能使其成為處理大規(guī)模數(shù)據(jù)和實時應用的理想選擇。

以上內容是否對您有幫助:
在線筆記
App下載
App下載

掃描二維碼

下載編程獅App

公眾號
微信公眾號

編程獅公眾號