Giter Site home page Giter Site logo

client-cpp's Introduction

tikv_logo

Build Status Coverage Status CII Best Practices

TiKV is an open-source, distributed, and transactional key-value database. Unlike other traditional NoSQL systems, TiKV not only provides classical key-value APIs, but also transactional APIs with ACID compliance. Built in Rust and powered by Raft, TiKV was originally created by PingCAP to complement TiDB, a distributed HTAP database compatible with the MySQL protocol.

The design of TiKV ('Ti' stands for titanium) is inspired by some great distributed systems from Google, such as BigTable, Spanner, and Percolator, and some of the latest achievements in academia in recent years, such as the Raft consensus algorithm.

If you're interested in contributing to TiKV, or want to build it from source, see CONTRIBUTING.md.

cncf_logo cncf_logo

TiKV is a graduated project of the Cloud Native Computing Foundation (CNCF). If you are an organization that wants to help shape the evolution of technologies that are container-packaged, dynamically-scheduled and microservices-oriented, consider joining the CNCF. For details about who's involved and how TiKV plays a role, read the CNCF announcement.


With the implementation of the Raft consensus algorithm in Rust and consensus state stored in RocksDB, TiKV guarantees data consistency. Placement Driver (PD), which is introduced to implement auto-sharding, enables automatic data migration. The transaction model is similar to Google's Percolator with some performance improvements. TiKV also provides snapshot isolation (SI), snapshot isolation with lock (SQL: SELECT ... FOR UPDATE), and externally consistent reads and writes in distributed transactions.

TiKV has the following key features:

  • Geo-Replication

    TiKV uses Raft and the Placement Driver to support Geo-Replication.

  • Horizontal scalability

    With PD and carefully designed Raft groups, TiKV excels in horizontal scalability and can easily scale to 100+ TBs of data.

  • Consistent distributed transactions

    Similar to Google's Spanner, TiKV supports externally-consistent distributed transactions.

  • Coprocessor support

    Similar to HBase, TiKV implements a coprocessor framework to support distributed computing.

  • Cooperates with TiDB

    Thanks to the internal optimization, TiKV and TiDB can work together to be a compelling database solution with high horizontal scalability, externally-consistent transactions, support for RDBMS, and NoSQL design patterns.

Governance

See Governance.

Documentation

For instructions on deployment, configuration, and maintenance of TiKV,see TiKV documentation on our website. For more details on concepts and designs behind TiKV, see Deep Dive TiKV.

Note:

We have migrated our documentation from the TiKV's wiki page to the official website. The original Wiki page is discontinued. If you have any suggestions or issues regarding documentation, offer your feedback here.

TiKV adopters

You can view the list of TiKV Adopters.

TiKV software stack

The TiKV software stack

  • Placement Driver: PD is the cluster manager of TiKV, which periodically checks replication constraints to balance load and data automatically.
  • Store: There is a RocksDB within each Store and it stores data into the local disk.
  • Region: Region is the basic unit of Key-Value data movement. Each Region is replicated to multiple Nodes. These multiple replicas form a Raft group.
  • Node: A physical node in the cluster. Within each node, there are one or more Stores. Within each Store, there are many Regions.

When a node starts, the metadata of the Node, Store and Region are recorded into PD. The status of each Region and Store is reported to PD regularly.

Quick start

Deploy a playground with TiUP

The most quickest to try out TiKV with TiDB is using TiUP, a component manager for TiDB.

You can see this page for a step by step tutorial.

Deploy a playground with binary

TiKV is able to run separately with PD, which is the minimal deployment required.

  1. Download and extract binaries.
$ export TIKV_VERSION=v7.5.0
$ export GOOS=darwin  # only {darwin, linux} are supported
$ export GOARCH=amd64 # only {amd64, arm64} are supported
$ curl -O  https://tiup-mirrors.pingcap.com/tikv-$TIKV_VERSION-$GOOS-$GOARCH.tar.gz
$ curl -O  https://tiup-mirrors.pingcap.com/pd-$TIKV_VERSION-$GOOS-$GOARCH.tar.gz
$ tar -xzf tikv-$TIKV_VERSION-$GOOS-$GOARCH.tar.gz
$ tar -xzf pd-$TIKV_VERSION-$GOOS-$GOARCH.tar.gz
  1. Start PD instance.
$ ./pd-server --name=pd --data-dir=/tmp/pd/data --client-urls="http://127.0.0.1:2379" --peer-urls="http://127.0.0.1:2380" --initial-cluster="pd=http://127.0.0.1:2380" --log-file=/tmp/pd/log/pd.log
  1. Start TiKV instance.
$ ./tikv-server --pd-endpoints="127.0.0.1:2379" --addr="127.0.0.1:20160" --data-dir=/tmp/tikv/data --log-file=/tmp/tikv/log/tikv.log
  1. Install TiKV Client(Python) and verify the deployment, required Python 3.5+.
$ pip3 install -i https://test.pypi.org/simple/ tikv-client
from tikv_client import RawClient

client = RawClient.connect("127.0.0.1:2379")

client.put(b'foo', b'bar')
print(client.get(b'foo')) # b'bar'

client.put(b'foo', b'baz')
print(client.get(b'foo')) # b'baz'

Deploy a cluster with TiUP

You can see this manual of production-like cluster deployment presented by @c4pt0r.

Build from source

See CONTRIBUTING.md.

Client drivers

If you want to try the Go client, see Go Client.

Security

Security audit

A third-party security auditing was performed by Cure53. See the full report here.

Reporting Security Vulnerabilities

To report a security vulnerability, please send an email to TiKV-security group.

See Security for the process and policy followed by the TiKV project.

Communication

Communication within the TiKV community abides by TiKV Code of Conduct. Here is an excerpt:

In the interest of fostering an open and welcoming environment, we as contributors and maintainers pledge to making participation in our project and our community a harassment-free experience for everyone, regardless of age, body size, disability, ethnicity, sex characteristics, gender identity and expression, level of experience, education, socio-economic status, nationality, personal appearance, race, religion, or sexual identity and orientation.

Social Media

Slack

Join the TiKV community on Slack - Sign up and join channels on TiKV topics that interest you.

License

TiKV is under the Apache 2.0 license. See the LICENSE file for details.

Acknowledgments

  • Thanks etcd for providing some great open source tools.
  • Thanks RocksDB for their powerful storage engines.
  • Thanks rust-clippy. We do love the great project.

client-cpp's People

Contributors

andylokandy avatar jayson-huang avatar smityz avatar venslu avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

client-cpp's Issues

Compile by docker

I think it's best to use Docker to compile a C++ project, to ensure consistency between the compilation environment and the production environment. I've written a Dockerfile based on CentOS 7 for this purpose, and I hope it can be merged into the master branch, and used as the foundation for developing a CI pipeline.

FROM centos:7.9.2009

RUN yum -y install centos-release-scl \
                   epel-release; \
                   yum -y install devtoolset-7-gcc \
                   devtoolset-7-gcc-c++ \
                   python3 \
                   make \
                   libtool \
                   openssl-devel \
                   yum clean all; \
                   rm -rf /var/cache/yum;

ENV PATH /opt/rh/devtoolset-7/root/bin/:$PATH
RUN pip3 install --upgrade pip --no-cache-dir && pip3 install --no-cache-dir cmake==3.26.4 -i https://pypi.tuna.tsinghua.edu.cn/simple

ENV RUSTUP_HOME=/usr/local/rustup CARGO_HOME=/usr/local/cargo
ENV PATH $CARGO_HOME/bin:$PATH
RUN mkdir -p "$CARGO_HOME" && mkdir -p "$RUSTUP_HOME" && \
    curl https://sh.rustup.rs -sSf | sh -s -- -y --default-toolchain 1.70.0 && \
    chmod -R a=rwX $CARGO_HOME
RUN cargo install cxxbridge-cmd --version 1.0.18

WORKDIR /client-cpp

Is the C++ Client still in development?

Hi @andylokandy & @JaySon-Huang,

Do you perchance know if this C++ Client for TiKV is still under development? If not, do you know what specific work needs to be done to bring this client up to par functionality-wise with the underlying Rust client?

Thanks for all of your excellent work on all of this!

libtikv_client.a 静态库封装成动态库无法使用

你好!我有个项目要使用tikv c++客户端,使用静态库后发现tikv openssl跟我自己的项目冲突,导致程序异常。我就想把tikv c++静态库编译成动态库,之后做符号的封装和隔离。但是封装成动态库后发现封装的动态库接口一直卡在初始化哪里,一直不动。请教一下你,能给点思路吗?或者看下哪里不对?多谢!@andylokandy
编译动态库的命令
g++ -shared -fPIC -o libexport.so export.cpp -L. -ltikv_client -lpthread -ldl -lssl -lcrypto -std=c++17

export.cpp的代码如下
#include "tikv_client.h"
#include
#include
#include
using namespace std;
using namespace tikv_client;

extern "C" TransactionClient *GetTransactionClient(const vector &ips);

TransactionClient *GetTransactionClient(const vector &ips)
{
//程序一直卡在这里,不动了!
TransactionClient *p = new TransactionClient(ips);
return p;
}

调用动态库
g++ -rdynamic -g -o Test myexport.cpp -L. -lpthread -lexport -ldl -lcrypto -std=c++17

myexport.cpp代码
int main() {
void *tikvso = dlopen("/home/test/test1/libexport.so", RTLD_NOW);
TransactionClient *(*pTransactionClient)(const vector &);
pTransactionClient = (TransactionClient ()(const vector &))dlsym(tikvso, "GetTransactionClient");
TransactionClient *client = (*pTransactionClient)({"172.19.255.198:2379"});
}

程序gdb调试,卡在new TransactionClient(ips); 这里,打印如下,就一直不动了。
[New Thread 0x7ffff2bf2700 (LWP 3507)]
[New Thread 0x7ffff29f1700 (LWP 3508)]
[New Thread 0x7ffff27f0700 (LWP 3509)]
[New Thread 0x7ffff25ef700 (LWP 3510)]
[New Thread 0x7ffff23ee700 (LWP 3511)]
[New Thread 0x7ffff1bed700 (LWP 3512)]

【Question】can I ask what is the exactly problem by saying "This client is still in the stage of prove-of-concept and under heavy development."

First of all , I am not a c/c++/rust expert. so my question may be ridiculous. forgive me for this.

as what I can tell, if this project build on top of project "client-rust", so we can trust it, because we can trust project "client-rust".

I mean this project(client-cpp) is only a thin wrapper layer, no logic code goes here at all. all what matter most codes are coded in project "client-rust".

so I don't know what is exactly problem of this project.

cpp sdk txn.put run throw excetpion

OS:
uname -a
Linux x.x.x.x 4.15.0-43-generic #46-Ubuntu SMP Thu Dec 6 14:45:28 UTC 2018 x86_64 x86_64 x86_64 GNU/Linux

`» config show all
{
"client-urls": "http://172.16.244.53:2379",
"peer-urls": "http://172.16.244.53:2380",
"advertise-client-urls": "http://172.16.244.53:2379",
"advertise-peer-urls": "http://172.16.244.53:2380",
"name": "pd1",
"data-dir": "/home/zgxie/pd/bin/pd1",
"force-new-cluster": false,
"enable-grpc-gateway": true,
"initial-cluster": "pd1=http://172.16.244.53:2380",
"initial-cluster-state": "new",
"initial-cluster-token": "pd-cluster",
"join": "",
"lease": 3,
"log": {
"level": "",
"format": "text",
"disable-timestamp": false,
"file": {
"filename": "",
"max-size": 0,
"max-days": 0,
"max-backups": 0
},
"development": false,
"disable-caller": false,
"disable-stacktrace": false,
"disable-error-verbose": true,
"sampling": null
},
"tso-save-interval": "3s",
"tso-update-physical-interval": "50ms",
"enable-local-tso": false,
"metric": {
"job": "pd1",
"address": "",
"interval": "15s"
},
"schedule": {
"max-snapshot-count": 3,
"max-pending-peer-count": 16,
"max-merge-region-size": 20,
"max-merge-region-keys": 200000,
"split-merge-interval": "1h0m0s",
"enable-one-way-merge": "false",
"enable-cross-table-merge": "true",
"patrol-region-interval": "100ms",
"max-store-down-time": "30m0s",
"leader-schedule-limit": 4,
"leader-schedule-policy": "count",
"region-schedule-limit": 2048,
"replica-schedule-limit": 64,
"merge-schedule-limit": 8,
"hot-region-schedule-limit": 4,
"hot-region-cache-hits-threshold": 3,
"store-limit": {
"1": {
"add-peer": 15,
"remove-peer": 15
},
"4": {
"add-peer": 15,
"remove-peer": 15
}
},
"tolerant-size-ratio": 0,
"low-space-ratio": 0.8,
"high-space-ratio": 0.7,
"region-score-formula-version": "v2",
"scheduler-max-waiting-operator": 5,
"enable-remove-down-replica": "true",
"enable-replace-offline-replica": "true",
"enable-make-up-replica": "true",
"enable-remove-extra-replica": "true",
"enable-location-replacement": "true",
"enable-debug-metrics": "false",
"enable-joint-consensus": "true",
"schedulers-v2": [
{
"type": "balance-region",
"args": null,
"disable": false,
"args-payload": ""
},
{
"type": "balance-leader",
"args": null,
"disable": false,
"args-payload": ""
},
{
"type": "hot-region",
"args": null,
"disable": false,
"args-payload": ""
},
{
"type": "label",
"args": null,
"disable": false,
"args-payload": ""
}
],
"schedulers-payload": {
"balance-hot-region-scheduler": null,
"balance-leader-scheduler": {
"name": "balance-leader-scheduler",
"ranges": [
{
"end-key": "",
"start-key": ""
}
]
},
"balance-region-scheduler": {
"name": "balance-region-scheduler",
"ranges": [
{
"end-key": "",
"start-key": ""
}
]
},
"label-scheduler": {
"name": "label-scheduler",
"ranges": [
{
"end-key": "",
"start-key": ""
}
]
}
},
"store-limit-mode": "manual"
},
"replication": {
"max-replicas": 3,
"location-labels": "",
"strictly-match-label": "false",
"enable-placement-rules": "true",
"isolation-level": ""
},
"pd-server": {
"use-region-storage": "true",
"max-gap-reset-ts": "24h0m0s",
"key-type": "table",
"runtime-services": "",
"metric-storage": "",
"dashboard-address": "http://172.16.244.53:2379",
"trace-region-flow": "true"
},
"cluster-version": "5.1.0-alpha",
"labels": {},
"quota-backend-bytes": "8GiB",
"auto-compaction-mode": "periodic",
"auto-compaction-retention-v2": "1h",
"TickInterval": "500ms",
"ElectionInterval": "3s",
"PreVote": true,
"security": {
"cacert-path": "",
"cert-path": "",
"key-path": "",
"cert-allowed-cn": null,
"redact-info-log": false,
"encryption": {
"data-encryption-method": "plaintext",
"data-key-rotation-period": "168h0m0s",
"master-key": {
"type": "plaintext",
"key-id": "",
"region": "",
"endpoint": "",
"path": ""
}
}
},
"label-property": {},
"WarningMsgs": null,
"DisableStrictReconfigCheck": false,
"HeartbeatStreamBindInterval": "1m0s",
"LeaderPriorityCheckInterval": "1m0s",
"dashboard": {
"tidb-cacert-path": "",
"tidb-cert-path": "",
"tidb-key-path": "",
"public-path-prefix": "",
"internal-proxy": false,
"enable-telemetry": true,
"enable-experimental": false
},
"replication-mode": {
"replication-mode": "majority",
"dr-auto-sync": {
"label-key": "",
"primary": "",
"dr": "",
"primary-replicas": 0,
"dr-replicas": 0,
"wait-store-timeout": "1m0s",
"wait-sync-timeout": "1m0s",
"wait-async-timeout": "2m0s"
}
}
}

» store
{
"count": 2,
"stores": [
{
"store": {
"id": 1,
"address": "172.16.244.53:20160",
"version": "5.1.0-alpha",
"status_address": "172.16.244.53:20180",
"git_hash": "cd905a208293c2b0c1fca9aa2756d5c26392b38c",
"start_timestamp": 1622467323,
"deploy_path": "/home/zgxie/test_tikv",
"last_heartbeat": 1622530962273867415,
"state_name": "Up"
},
"status": {
"capacity": "492.1GiB",
"available": "385.3GiB",
"used_size": "336.3MiB",
"leader_count": 35,
"leader_weight": 1,
"leader_score": 35,
"leader_size": 3241,
"region_count": 61,
"region_weight": 1,
"region_score": 9590.902448098743,
"region_size": 5736,
"start_ts": "2021-05-31T21:22:03+08:00",
"last_heartbeat_ts": "2021-06-01T15:02:42.273867415+08:00",
"uptime": "17h40m39.273867415s"
}
},
{
"store": {
"id": 4,
"address": "172.16.244.142:20160",
"version": "5.1.0-alpha",
"status_address": "172.16.244.142:20180",
"git_hash": "cd905a208293c2b0c1fca9aa2756d5c26392b38c",
"start_timestamp": 1622467323,
"deploy_path": "/home/zgxie/test_tikv",
"last_heartbeat": 1622530960400607535,
"state_name": "Up"
},
"status": {
"capacity": "492.1GiB",
"available": "434.3GiB",
"used_size": "320.4MiB",
"leader_count": 26,
"leader_weight": 1,
"leader_score": 26,
"leader_size": 2495,
"region_count": 61,
"region_weight": 1,
"region_score": 9321.07932558792,
"region_size": 5736,
"start_ts": "2021-05-31T21:22:03+08:00",
"last_heartbeat_ts": "2021-06-01T15:02:40.400607535+08:00",
"uptime": "17h40m37.400607535s"
}
}
]
}`

demo:

`void test_put( tikv_client::TransactionClient & client, int count ){

auto txn = client.begin();
for( int i=1;i<=count;i++){
    sprintf( keyName, "k%d", i );
    txn.put( keyName, keyValue );

    if(i%3000== 0){
        txn.commit();
        txn = client.begin();
    }
}

txn.commit();

}

int main( int argc, char **argv) {

tikv_client::TransactionClient client = tikv_client::TransactionClient({"172.16.244.53:2379"});
int count;
sscanf( argv[1], "%d", &count);
auto begin_tm = timeSinceEpochMillisec();
test_put( client, count );
auto end_tm = timeSinceEpochMillisec();
printf("time:%ld\n", end_tm- begin_tm);
return 0;

}`

result error:
1、terminate called after throwing an instance of 'rust::cxxbridge1::Error'
what(): Failed to resolve lock
2、terminate called after throwing an instance of 'rust::cxxbridge1::Error'
what(): Region error: Error { message: "raft entry is too large, region 2, entry size 21270018", not_leader: None, region_not_found: None, key_not_in_region: None, epoch_not_match: None, server_is_busy: None, stale_command: None, store_not_match: None, raft_entry_too_large: Some(RaftEntryTooLarge { region_id: 2, entry_size: 21270018 }), max_timestamp_not_synced: None, read_index_not_ready: None, proposal_in_merging_mode: None }
3、terminate called after throwing an instance of 'rust::cxxbridge1::Error'
what(): gRPC error: RpcFailure: 4-DEADLINE_EXCEEDED Deadline Exceeded

Question: How to handle error thrown by TiKV

## Setup a cluster by TiUP playground
client-cpp>  tiup playground --nightly

## Then run the example program of `tikv/client-cpp`
client-cpp> make run-example
RUST_LOG=debug /data3/my/client-cpp/target/tikv-example
[2021-03-02T14:29:15Z INFO  tikv_client_common::security] connect to rpc server at endpoint: "127.0.0.1:2379"
[2021-03-02T14:29:15Z WARN  tikv_client_pd::cluster] PD endpoint 127.0.0.1:2379 failed to respond: Grpc(RpcFailure(RpcStatus { status: 14-UNAVAILABLE, details: Some("failed to connect to all addresses") }))
terminate called after throwing an instance of 'rust::cxxbridge1::Error'
  what():  [/root/.cargo/git/checkouts/client-rust-5a1ccd35a54db20f/89ac804/tikv-client-pd/src/cluster.rs:174]: PD cluster failed to respond
make: *** [run-example] Aborted

client-cpp>  make run-example
RUST_LOG=debug /data3/my/client-cpp/target/tikv-example
[2021-03-02T14:30:34Z INFO  tikv_client_common::security] connect to rpc server at endpoint: "127.0.0.1:2379"
[2021-03-02T14:30:34Z INFO  tikv_client_pd::cluster] All PD endpoints are consistent: ["127.0.0.1:2379"]
[2021-03-02T14:30:34Z INFO  tikv_client_common::security] connect to rpc server at endpoint: "http://127.0.0.1:2379"
[2021-03-02T14:30:34Z INFO  tikv_client_common::security] connect to rpc server at endpoint: "http://127.0.0.1:2379"
get key k1:v2
terminate called after throwing an instance of 'rust::cxxbridge1::Error'
  what():  Leader of region 2 is not found
make: *** [run-example] Aborted

I try to run the example program while setting up a tiup-playground cluster, it throws some errors.

For example, if I want to write some code to handle leader not found error, now I have to write it like

    auto txn = client.begin();

    txn.put("k1", "v2");

    bool success = false;
    while (!success) {
        try {
            txn.commit();
            success = true;
        } catch (rust::cxxbridge1::Error &e) {
            // Ignore Leader not found and try to commit again
            std::string err_msg = e.what();
            if (err_msg.find("Leader of region") == std::string::npos) {
                // Other error, throw exception
                throw;
            }
        }
    }

Can client-cpp throw different kind of Exception? So I can write codes like:

    auto txn = client.begin();

    txn.put("k1", "v2");

    bool success = false;
    while (!success) {
        try {
            txn.commit();
            success = true;
        } catch (tikv_client::LeaderNotFoundException &e) {
            // Ignore Leader not found and try to commit again
        }
    }

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.