Youtube の紹介 • Discord チャット • 完全なドキュメント
UStore のインストールは簡単で、使用方法も Python dict
と同じくらい簡単です。
$ pip install ukv
$ python
from ukv import umem
db = umem . DataBase ()
db . main [ 42 ] = 'Hi'
インメモリ組み込みトランザクション データベースを作成し、そのmain
コレクションに 1 つのエントリを追加しました。そのデータをディスク上に置きますか? 1行変更します。
from ukv import rocksdb
db = rocksdb . DataBase ( '/some-folder/' )
リモート UStore サーバーに接続しますか? UStore には Apache Arrow Flight RPC インターフェイスが付属しています。
from ukv import flight_client
db = flight_client . DataBase ( 'grpc://0.0.0.0:38709' )
NetworkX のようなMultiDiGraph
を保存していますか?それともパンダのようなDataFrame
でしょうか?
db = rocksdb . DataBase ()
users_table = db [ 'users' ]. table
users_table . merge ( pd . DataFrame ([
{ 'id' : 1 , 'name' : 'Lex' , 'lastname' : 'Fridman' },
{ 'id' : 2 , 'name' : 'Joe' , 'lastname' : 'Rogan' },
]))
friends_graph = db [ 'friends' ]. graph
friends_graph . add_edge ( 1 , 2 )
assert friends_graph . has_edge ( 1 , 2 ) and
friends_graph . has_node ( 1 ) and
friends_graph . number_of_edges ( 1 , 2 ) == 1
関数呼び出しは同じように見えますが、基礎となる実装は、リモート マシン上の永続メモリのどこかに配置された数百テラバイトのデータに対処することができます。
他の誰かがこれらのコレクションを同時に更新しているのでしょうか?一貫性を保証するために操作をバンドルしてください。
db = rocksdb . DataBase ()
with db . transact () as txn :
txn [ 'users' ]. table . merge (...)
txn [ 'friends' ]. graph . add_edge ( 1 , 2 )
これまでのところ、UStore の先端部分だけを取り上げてきました。次の目的で使用できます...
しかし、UStore ではそれ以上のことができます。地図は次のとおりです。
## 基本的な使い方
UStore は、単なるデータベースとしてではなく、「データベースの構築」ツールキットとして、およびトランザクション可能な NoSQL データベースのオープン スタンダードとして意図されており、「作成、読み取り、更新、削除」操作 (略して CRUD) のためのゼロコピー バイナリ インターフェイスを定義しています。
いくつかの単純な C99 ヘッダーは、ほぼすべての基盤となるストレージ エンジンを多数の高級言語ドライバーにリンクし、バイナリ文字列値のサポートをグラフ、柔軟なスキーマ ドキュメント、その他のモダリティに拡張し、MongoDB、Neo4J、Pinecone、および ElasticSearch を置き換えることを目的としています。単一の ACID トランザクション システムを使用します。
たとえば、Redis は、同様の目的を備えた RediSearch、RedisJSON、および RedisGraph を提供します。 UStore はそれをさらに優れており、組み込み、スタンドアロン、または FoundationDB などのシャード化されたお気に入りの Key-Value ストア (KVS) を追加して、その機能を倍増できます。
バイナリ ラージ オブジェクトは UStore 内に配置できます。パフォーマンスは、使用されている基盤テクノロジーによって大きく異なります。インメモリ UCSet は最も高速ですが、大きなオブジェクトには最も適していません。永続 UDisk は、適切に構成されている場合、ファイル システム層を含む Linux カーネルを完全にバイパスして、ブロック デバイスを直接アドレス指定できます。
ハイエンド サーバー上の最新の永続 IO は、SPDK などのユーザー空間ドライバー上に構築されている場合、ソケットあたり 100 GB/秒を超えることがあります。これはハイエンド RAM の実際のスループットに近く、データベースでは珍しい新しいユースケースを可能にします。 MinIO などの別個のオブジェクト ストアを使用する代わりに、ギガバイト サイズのビデオ ファイルを ACID トランザクション データベースのメタデータのすぐ隣に置くことができるようになりました。
JSON は、最近最も一般的に使用されているドキュメント形式です。 UStore ドキュメント コレクションは、MongoDB で使用される JSON、MessagePack、BSON をサポートします。
UStore はまだ水平方向に拡張できませんが、オープンソースのsimdjson
およびyyjson
ライブラリのおかげで、はるかに高い単一ノードのパフォーマンスを提供し、メニーコア システム上でほぼ直線的な垂直方向の拡張性を備えています。さらに、データを操作するために、MQL のようなカスタム クエリ言語は必要ありません。代わりに、ベンダー ロックを真に回避するために、オープンな RFC 標準を優先します。
Neo4J のような最新の Graph データベースは、大規模なワークロードに苦戦しています。大量の RAM を必要とし、アルゴリズムは一度に 1 エントリずつデータを監視します。私たちは次の両方の面で最適化します。
Pinecone、Milvus、USearch などの特徴ストアとベクトル データベースは、ベクトル検索用のスタンドアロン インデックスを提供します。 UStore は、Documents や Graphs と同等の別個のモダリティとしてこれを実装します。特徴:
Python 用と C++ 用の UStore は大きく異なります。私たちの Python SDK は、他の Python ライブラリ (Pandas や NetworkX) を模倣しています。同様に、C++ ライブラリは、C++ 開発者が期待するインターフェイスを提供します。
ご存知のとおり、人々はさまざまな目的にさまざまな言語を使用します。一部の C レベルの機能は、一部の言語では実装されていません。需要がなかったか、まだそれに到達していないためです。
名前 | 取引する | コレクション | バッチ | ドキュメント | グラフ | コピー |
---|---|---|---|---|---|---|
C99スタンダード | ✓ | ✓ | ✓ | ✓ | ✓ | 0 |
C++ SDK | ✓ | ✓ | ✓ | ✓ | ✓ | 0 |
Python SDK | ✓ | ✓ | ✓ | ✓ | ✓ | 0-1 |
GoLang SDK | ✓ | ✓ | ✓ | ✗ | ✗ | 1 |
Java SDK | ✓ | ✓ | ✗ | ✗ | ✗ | 1 |
アローフライトAPI | ✓ | ✓ | ✓ | ✓ | ✓ | 0-2 |
ここの一部のフロントエンドには、その周囲にエコシステム全体が存在します。たとえば、Apache Arrow Flight API には、C、C++、C#、Go、Java、JavaScript、Julia、MATLAB、Python、R、Ruby、Rust 用の独自のドライバーがあります。
以下のエンジンはほぼ互換的に使用できます。歴史的には、LevelDB が最初のものでした。その後、RocksDB は機能とパフォーマンスを向上させました。現在、これは DBMS スタートアップの半数の基盤として機能しています。
レベルDB | ロックスDB | Uディスク | UCセット | |
---|---|---|---|---|
スピード | 1x | 2倍 | 10倍 | 30倍 |
持続的 | ✓ | ✓ | ✓ | ✗ |
トランザクション | ✗ | ✓ | ✓ | ✓ |
ブロックデバイスのサポート | ✗ | ✗ | ✓ | ✗ |
暗号化 | ✗ | ✗ | ✓ | ✗ |
時計 | ✗ | ✓ | ✓ | ✓ |
スナップショット | ✓ | ✓ | ✓ | ✗ |
ランダムサンプリング | ✗ | ✗ | ✓ | ✓ |
一括列挙 | ✗ | ✗ | ✓ | ✓ |
名前付きコレクション | ✗ | ✓ | ✓ | ✓ |
オープンソース | ✓ | ✓ | ✗ | ✓ |
互換性 | どれでも | どれでも | Linux | どれでも |
メンテナー | グーグル | フェイスブック | ウヌム | ウヌム |
UCSet と UDisk は両方とも Unum によって設計および保守されています。どちらも機能は完備していますが、代替品が提供する最も重要な機能はパフォーマンスです。記憶が速いのは簡単です。 UCSet のコア ロジックは、テンプレート化されたヘッダーのみのucset
ライブラリにあります。
UDisk の設計は、7 年にわたる非常に困難な作業でした。これには、新しいツリー状構造の発明、 io_uring
による部分的なカーネル バイパス、 SPDK
による完全なバイパス、CUDA GPU アクセラレーション、さらにはカスタム内部ファイル システムの実装が含まれていました。 UDisk は、並列アーキテクチャとカーネル バイパスを念頭に置いて最初から設計された最初のエンジンです。
原子性は常に保証されます。非トランザクション書き込みの場合でも、すべての更新が成功するか、すべて失敗します。
一貫性は可能な限り厳密な形式で実装されます。「厳密な直列化可能性」とは、次のことを意味します。
ただし、デフォルトの動作は、特定の操作のレベルで調整できます。そのため、 ::ustore_option_transaction_dont_watch_k
ustore_transaction_init()
またはトランザクション読み取り/書き込み操作に渡して、ステージング中の一貫性チェックを制御できます。
読み取り | 書き込みます | |
---|---|---|
頭 | 厳密なシリアル | 厳密なシリアル |
スナップショットを介したトランザクション | シリアル | 厳密なシリアル |
スナップショットのないトランザクション | 厳密なシリアル | 厳密なシリアル |
ウォッチを使用しないトランザクション | 厳密なシリアル | 一連 |
このトピックが初めての方は、一貫性に関する Jepsen.io ブログをご覧ください。
読み取り | 書き込みます | |
---|---|---|
スナップショットを介したトランザクション | ✓ | ✓ |
スナップショットのないトランザクション | ✗ | ✓ |
定義上、耐久性はインメモリ システムには適用されません。ハイブリッドまたは永続システムでは、デフォルトで無効にすることを好みます。 KVS 上に構築されるほぼすべての DBMS は、独自の耐久性メカニズムを実装することを好みます。分散データベースでは、3 つの個別の先行書き込みログが存在する可能性があるため、さらにそうです。
それでも耐久性が必要な場合は、オプションのフラグを使用してコミット時の書き込みをフラッシュします。 C ドライバーでは、 ::ustore_option_write_flush_k
フラグを指定してustore_transaction_commit()
を呼び出します。
DBMS 全体は 100 MB 未満の Docker イメージに収まります。次のスクリプトを実行してコンテナをプルして実行し、ポート38709
で Apache Arrow Flight サーバーを公開します。クライアント SDK も、デフォルトでは同じポートを介して通信します。
docker run -d --rm --name ustore-test -p 38709:38709 unum/ustore
デフォルトの構成ファイルは次のコマンドで取得できます。
cat /var/lib/ustore/config.json
接続してテストする最も簡単な方法は、次のコマンドです。
python ...
事前にパッケージ化された UStore イメージは、複数のプラットフォームで利用できます。
UStore の商用化と再配布を躊躇しないでください。
データベースのチューニングは科学であると同時に芸術でもあります。 RocksDB のようなプロジェクトでは、動作を最適化するための多数のノブが提供されています。特殊な構成ファイルを基礎となるエンジンに転送できるようにします。
{
"version" : " 1.0 " ,
"directory" : " ./tmp/ "
}
ユーザーの 80% にとってはこれで十分な、より簡単な手順もあります。これを拡張して、複数のデバイスやディレクトリを利用したり、特殊なエンジン構成を転送したりできます。
{
"version" : " 1.0 " ,
"directory" : " /var/lib/ustore " ,
"data_directories" : [
{
"path" : " /dev/nvme0p0/ " ,
"max_size" : " 100GB "
},
{
"path" : " /dev/nvme1p0/ " ,
"max_size" : " 100GB "
}
],
"engine" : {
"config_file_path" : " ./engine_rocksdb.ini " ,
}
}
データベース コレクションは JSON ファイルを使用して構成することもできます。
現在のバージョンでは、64 ビットの符号付き整数が使用されます。 [0, 2^63)
の範囲の一意のキーが許可されます。 UUID を使用した 128 ビット ビルドが予定されていますが、可変長キーの使用は強く推奨されません。なぜそうなるのでしょうか?
可変長キーを使用すると、Key-Value ストアの設計に多くの制限が課せられます。まず、これは文字ごとの比較が遅いことを意味しており、最新のハイパースカラー CPU ではパフォーマンスを低下させます。次に、ナビゲーションに必要なメタデータを最小限に抑えるために、キーと値をディスク上で強制的に結合します。最後に、これは KVS を「永続メモリ アロケーター」として考える単純な論理的見解に違反し、より多くの責任を KVS に課すことになります。
文字列キーを処理するための推奨されるアプローチは次のとおりです。
これにより、文字列表現から整数表現への変換ポイントが 1 つになり、システムの大部分がスムーズに動作し、C レベルのインターフェイスが以前よりも単純になります。
現時点では、4 GB 以下の値のみに対応できます。なぜ? Key-Value ストアは通常、高頻度の操作を目的としています。頻繁に (毎秒数千回) 4 GB 以上のファイルにアクセスして変更することは、最新のハードウェアでは不可能です。したがって、私たちはより小さい長さの型にこだわり、Apache Arrow 表現の使用を若干容易にし、KVS がインデックスをより適切に圧縮できるようにします。
私たちの開発ロードマップは公開されており、GitHub リポジトリ内でホストされています。今後のタスクには次のものが含まれます。
ここのドキュメントで完全なロードマップをお読みください。