安裝部署
安裝包安裝/解除安裝
這種方式友善快捷,隻需要下載下傳自己系統對應的包即可。
解除安裝的時候需要注意清理掉環境中的 舊版本的資料以及 配置檔案:
sudo rm -rf /var/lib/foundationdb /var/log/foundationdb /etc/foundationdb/fdb.cluster
Centos
wget https://github.com/apple/foundationdb/releases/download/7.1.0/foundationdb-server-7.1.0-1.el7.x86_64.rpm
wget https://github.com/apple/foundationdb/releases/download/7.1.0/foundationdb-clients-7.1.0-1.el7.x86_64.rpm
# Install
sudo rpm -Uvh foundationdb-clients-7.1.0-1.el7.x86_64.rpm foundationdb-server-7.1.0-1.el7.x86_64.rpm
# Uninstall
sudo rpm -e --nodeps foundationdb-clients foundationdb-server
Ubuntu
wget https://github.com/apple/foundationdb/releases/download/7.1.0/foundationdb-server_7.1.0-1_amd64.deb
wget https://github.com/apple/foundationdb/releases/download/7.1.0/foundationdb-clients_7.1.0-1_amd64.de
# Install
sudo dpkg -i foundationdb-clients_7.1.0-1_amd64.deb foundationdb-server_7.1.0-1_amd64.deb
# Uninstall
sudo dpkg -P foundationdb-clients foundationdb-server
Mac
直接下載下傳一個 pkg 包即可
wget https://github.com/apple/foundationdb/releases/download/7.1.0/FoundationDB-7.1.0.pkg
安裝完成之後foundationdb 會直接啟動
![](https://img.laitimes.com/img/_0nNw4CM6IyYiwiM6ICdiwiI0gTMx81dsQWZ4lmZf1GLlpXazVmcvwFciV2dsQXYtJ3bm9CX9s2RkBnVHFmb1clWvB3MaVnRtp1XlBXe0xCMy81dvRWYoNHLwEzX5xCMx8FesU2cfdGLwMzX0xiRGZkRGZ0Xy9GbvNGLpZTY1EmMZVDUSFTU4VFRR9Fd4VGdsYTMfVmepNHLrJXYtJXZ0F2dvwVZnFWbp1zczV2YvJHctM3cv1Ce-cmbw5iNwYjM4EWY5czMmVmM4QjNzYzXzQTMxETM0AzLcFTMyIDMy8CXn9Gbi9CXzV2Zh1WavwVbvNmLvR3YxUjLyM3Lc9CX6MHc0RHaiojIsJye.png)
可以通過
service foundationdb start/stop/status
來控制目前單機環境的下的foundationdb 的配置。
當然,你可以啟動多個fdbserver,對多個server 通過
/etc/foundationdb/foundationdb.conf
進行不同的角色配置,所有 foundationdb 論文中的 coordinator / log-server / proxy 等 角色都是一個fdbserver 程序,該程序擁有這個角色的配置而已。
源碼編譯 安裝
一般有源碼編譯的需求是希望能夠調試 fdb 内部運作的一些代碼,可以在源碼場景進行編譯,
-
下載下傳foundationdb 源碼 并 checkout 到指定分支:
git clone https://github.com/apple/foundationdb.git && cd foundationdb && git checkout 7.1.0
- 更新環境的 cmake,要求版本大于等于
3.13
-
安裝 mono(跨平台開發的工具,在一個平台可以開發其他平台的應用),foundationdb 編譯的時候依賴這個東西,
可以從 mono-官網 直接進行安裝,比較友善。
- 安裝
Ninja
或者 不用安裝,直接用make。 Ninja 是用 C++ 寫的小型的編譯工具,非常友善且高性能。
其他平台也可以直接搜尋安裝,或者去官網進行安裝sudo apt-get install ninja-build
- 編譯 FoundationDB
cd foundationdb && mkdir build && cd build
# 之是以關閉掉rocksdb,是因為rocksdb 目前還是試驗性的,沒有上生産環境
cmake -G Ninja .. -DWITH_ROCKSDB_EXPERIMENTAL=OFF
ninja -j10
- 編譯後的二進制會放在
目錄下, lib庫會放在 bin
lib
目錄下。
啟動的話直接啟動一個 fdbserver 程序就夠了,該程序能夠和用戶端進行互動
sudo ./bin/fdbserver --cluster-file /etc/foundationdb/fdb.cluster --datadir /var/lib/foundationdb/data/4500 --listen-address public --logdir /var/log/foundationdb --public-address auto:4500
對于以上兩種安裝方式,最後啟動了fdbserver 之後,我們可以直接通過
fdbcli
做一些測試:
$ fdbcli
Using cluster file `/etc/foundationdb/fdb.cluster'.
The database is available.
Welcome to the fdbcli. For help, type `help'.
fdb> status
Using cluster file `/etc/foundationdb/fdb.cluster'.
Configuration:
Redundancy mode - single
Storage engine - memory-2
Coordinators - 1
Usable Regions - 1
...
fdb> begin
Transaction started
fdb> writemode on
fdb> set a b
fdb> set a c
fdb> get a
`a' is `c'
fdb> commit
Committed (250049167890)
fdb> get a
`a' is `c
...
到此,整個 fdb 叢集就是可用的了。
C-API 使用
FDB 将 C++ 接口做了 C 的封裝,直接和 fdb-client API 進行互動,我們可以通過 C 接口啟動一個類似 fdbcli 的服務和 fdb-client進行互動。
關于 C-API 的使用文檔, 可以參考 fdb c-api。
可以參考如下測試代碼 對基本接口的使用,因為整個fdb 的内部接口(從client->server)都是依賴 Future 異步程式設計架構實作的,是以使用上還是需要有很多注意的地方。
而且因為異步架構的問題,很多接口調用之後傳回,内部隻是設定一個标記(fdb_database_set_option/fdb_transaction_set_option 等接口 并不是立即在server層進行設定),是以想要利用gdb 分析fdb 的内部實作複雜度還是挺高的,隻能一點點撸代碼了。
多租戶的實作是fdb 7系版本之後支援的,允許不同的使用者指定自己的租戶名,不同租戶之間的資料是不可見的。
#define FDB_API_VERSION 710
#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <fdb_c.h>
#include <unistd.h>
FDBTenant *fdb_tenant = NULL;
FDBTransaction *tr = NULL;
FDBDatabase *db = NULL;
pthread_t netThread;
static void checkError(fdb_error_t errorNum) {
if (errorNum) {
fprintf(stderr, "Error (%d): %s\n", errorNum, fdb_get_error(errorNum));
exit(errorNum);
}
}
static void waitAndCheckError(FDBFuture *future) {
checkError(fdb_future_block_until_ready(future));
if (fdb_future_get_error(future) != 0) {
checkError(fdb_future_get_error(future));
}
}
static void runNetwork() { checkError(fdb_run_network()); }
void createDataInDatabase() {
int committed = 0;
/* Create transaction. */
checkError(fdb_database_create_transaction(db, &tr));
while (!committed) {
/* Create data */
char *key1 = "Test Key1";
char *val1 = "Test Value1";
fdb_transaction_set(tr, key1, (int)strlen(key1), val1, (int)strlen(val1));
/* Commit to database.*/
FDBFuture *commitFuture = fdb_transaction_commit(tr);
checkError(fdb_future_block_until_ready(commitFuture));
if (fdb_future_get_error(commitFuture) != 0) {
waitAndCheckError(
fdb_transaction_on_error(tr, fdb_future_get_error(commitFuture)));
} else {
committed = 1;
}
fdb_future_destroy(commitFuture);
}
/* Destroy transaction. */
fdb_transaction_destroy(tr);
}
void createTenantDataAndReadData() {
char *tenant_name = "example";
FDBTransaction *tr = NULL;
FDBTransaction *tr2 = NULL;
fdb_bool_t valuePresent;
int valueLength;
const uint8_t *value = NULL;
const char *k1 = "tenant key1";
const char *v1 = "tenant value1";
checkError(fdb_database_open_tenant(db, (uint8_t const *)tenant_name,
strlen(tenant_name), &fdb_tenant));
checkError(fdb_tenant_create_transaction(fdb_tenant, &tr));
fdb_transaction_set(tr, k1, (int)strlen(k1), v1, (int)strlen(v1));
FDBFuture *commitFuture = fdb_transaction_commit(tr);
checkError(fdb_future_block_until_ready(commitFuture));
if (fdb_future_get_error(commitFuture) != 0) {
waitAndCheckError(
fdb_transaction_on_error(tr, fdb_future_get_error(commitFuture)));
}
fdb_transaction_destroy(tr);
fdb_future_destroy(commitFuture);
checkError(fdb_tenant_create_transaction(fdb_tenant, &tr2));
FDBFuture *getFuture = fdb_transaction_get(tr2, k1, (int)strlen(k1), 0);
waitAndCheckError(getFuture);
checkError(
fdb_future_get_value(getFuture, &valuePresent, &value, &valueLength));
printf("Get value from tenant , key : %s, value : %s, value-len : %d\n", k1,
value, valueLength);
fdb_transaction_destroy(tr2);
fdb_future_destroy(getFuture);
}
void readDataFromDatabase() {
FDBTransaction *tr = NULL;
const uint8_t *value = NULL;
fdb_bool_t valuePresent;
int valueLength;
char *key = "Test Key1";
checkError(fdb_database_create_transaction(db, &tr));
FDBFuture *getFuture = fdb_transaction_get(tr, key, (int)strlen(key), 0);
waitAndCheckError(getFuture);
checkError(
fdb_future_get_value(getFuture, &valuePresent, &value, &valueLength));
printf("Got Value from db. %s: '%.*s'\n", key, valueLength, value);
fdb_transaction_destroy(tr);
fdb_future_destroy(getFuture);
}
int main() {
/* Default fdb cluster file. */
char *cluster_file = "/etc/foundationdb/fdb.cluster";
/* Setup network. */
checkError(fdb_select_api_version(FDB_API_VERSION));
checkError(fdb_setup_network());
puts("Created network.");
pthread_create(&netThread, NULL, (void *)runNetwork, NULL);
checkError(fdb_create_database(cluster_file, &db));
puts("Created database.");
/*Create tenant and do nothing.*/
createDataInDatabase();
readDataFromDatabase();
createTenantDataAndReadData();
puts("Program done. Now exiting...");
fdb_tenant_destroy(fdb_tenant);
fdb_tenant = NULL;
fdb_database_destroy(db);
db = NULL;
checkError(fdb_stop_network());
int rc = pthread_join(netThread, NULL);
if (rc)
fprintf(stderr, "ERROR: network thread failed to join\n");
exit(0);
}
gcc test_fdb.c -lfdb_c -lpthread -I /usr/include/foundationdb/ -ggdb3 -O0 -g3 -o test_fdb
$ ./test_fdb
Created network.
Created database.
committing key/value.
Got Value : Test Key1: 'Test Value1'
Get value from tenant , key : tenant key1, value : tenant value1, value-len : 13
Program done. Now exiting...
性能測試
在前面的源碼編譯過程中,會編譯出來一個叫做
mako
的binary,它會被放在
bin/mako
中。是fdb 官方提供的 C 接口實作的小型性能測試工具,能夠對目前部署的fdb 環境做一些基本的性能測試,更多細節可以參考描述文檔:
灌資料:
./mako --cluster /etc/foundationdb/fdb.cluster --mode build --rows 10000000 --procs 4
灌資料結束之後,接下來可以在已有的資料集的基礎上做一些組合性能的測試:
啟動兩個worker,每一個worker 8個線程, workload是:
g8ui
,表示 80%的get + 10% 的updates + 10%的inserts
./mako --cluster /etc/foundationdb/fdb.cluster --mode run --rows 1000000 --procs 2 --threads 8 --transaction "g8ui" --seconds 60
- 100% 讀,
g100
- 100% updates.
u100
- 100% insert.
i100
- range 讀寫 以及 控制讀寫比例,可以參考