JavaによるCockroachDBガイド

1前書き

このチュートリアルはCockroachDBをJavaと共に使用するための入門ガイドです。

ここでは、主な機能、ローカルクラスタの設定方法、および監視方法について説明します。また、Javaを使用してサーバーに接続して対話する方法についての実用的なガイドも説明します。

まずそれが何であるかを定義することから始めましょう。

2ゴキブリDB

CockroachDBは、トランザクションと一貫性のあるKey-Valueストアの上に構築された分散SQLデータベースです。

Goで書かれ、完全にオープンソース化された** その主な設計目標は、ACIDトランザクションのサポート、水平方向のスケーラビリティ、および存続可能性です。手動の介入なしで混乱。

その結果、CockroachDBは規模に関係なく信頼性があり、利用可能で正しいデータを必要とするアプリケーションに最適なソリューションと見なすことができます。

2.1. 主な機能

CockroachDBの重要な側面のいくつかを探り続けましょう。

  • SQL APIとPostgreSQLの互換性 - 構造化、操作用

データの照会 ACIDトランザクション** - 分散トランザクションのサポートと提供

強い一貫性 クラウド対応** - クラウドまたはオンプレミスで実行するように設計されています

異なるクラウドプロバイダー間で簡単に移行できるソリューション サービスを中断することなく 水平方向に拡大縮小** - 容量を追加するのは、新しい人を指すのと同じくらい簡単

実行中のクラスタのノードで、最小限のオペレータオーバーヘッド 複製** - 可用性と保証のためにデータを複製します。

レプリカ間の一貫性 自動修復** - の大部分である限りシームレスに継続

レプリカは短期間の障害でも使用可能なままですが、長期間の障害では、影響を受けていないレプリカをソースとして使用して、不足しているノードからレプリカを自動的に再調整します。

3 CockroachDB の設定

CockroachDB をインストールしたら、ローカルクラスタの最初のノードを起動できます。

cockroach start --insecure --host=localhost;

デモ目的では、証明書の場所を指定する必要なく、 insecure 属性を使用して通信を暗号化しません。

この時点で、私たちのローカルクラスタは稼働しています。 1つのノードしかなくても、それに接続して操作することはできますが、CockroachDBの自動複製、リバランス、およびフォールトトレランスをさらに活用するには、さらに2つのノードを追加します。

cockroach start --insecure --store=node2 \
  --host=localhost --port=26258 --http-port=8081 \
  --join=localhost:26257;

cockroach start --insecure --store=node3 \
  --host=localhost --port=26259 --http-port=8082 \
  --join=localhost:26257;

2つの追加ノードでは、 join フラグを使用して新しいノードをクラスタに接続し、最初のノードのアドレスとポートを指定しています。この場合はlocalhost:26257です。 ** ローカルクラスタの各ノードには、一意の store port 、および http-port 値が必要です。

CockroachDBの分散クラスタを設定する場合、各ノードは異なるマシン上にあります。したがって、デフォルト値で十分なので、 port store 、および http-port の指定は避けられます。さらに、最初のノードの実際のIPは、追加のノードをクラスタに参加させるときに使用する必要があります。

3.1. データベースとユーザーの設定

CockroachDBに付属のSQLコンソールを使ってクラスタを起動し、実行したら、データベースとユーザーを作成する必要があります。

まず最初に、SQLコンソールを起動しましょう。

cockroach sql --insecure;

それでは、CRUD操作を実行できるように、 testdb データベースを作成し、ユーザーを作成してそのユーザーに権限を追加しましょう。

CREATE DATABASE testdb;
CREATE USER user17 with password 'qwerty';
GRANT ALL ON DATABASE testdb TO user17;

データベースが正しく作成されたことを確認したい場合は、現在のノードに作成されたすべてのデータベースを一覧表示できます。

SHOW DATABASES;

最後に、CockroachDBの自動複製機能を検証したい場合は、データベースが正しく作成されているかどうかを確認してください。そのためには、SQLコンソールを使用しているときに port フラグを表現する必要があります。

cockroach sql --insecure --port=26258;

4 CockroachのモニタリングDB

ローカルクラスタを起動してデータベースを作成したので、CockroachDB管理UIを使用してそれらを監視できます。

CockroachDBとバンドルされているこの管理UIは、クラスタが起動して実行されるとすぐに http://localhost:8080 にアクセスできます。特に、 クラスタとデータベースの設定に関する詳細を提供し、 などのメトリクスを監視することでクラスタのパフォーマンスを最適化するのに役立ちます。

  • クラスタの健全性 - クラスタの健全性に関する重要な指標

  • Runtime Metrics - ノード数、CPU時間、メモリに関するメトリクス

使用法 SQLパフォーマンス** - SQL接続、クエリ、および統計に関するメトリクス

取引 複製の詳細** - データがどのように複製されるかについての測定基準

クラスタ Node Details ** - ライブ、デッド、廃止されたノードの詳細

  • データベースの詳細 - システムとユーザーデータベースに関する詳細

クラスタ

5. プロジェクト設定

実行しているCockroachDBのローカルクラスタを考えると、それに接続できるようにするには、https://search.maven.org/classic/#search%7Cga%7C1%7Cg%3A%22org.postgresql%を追加する必要があります22%20AND%20a%3A%22postgresql%22 pom.xmlへの[追加の依存関係]:

<dependency>
    <groupId>org.postgresql</groupId>
    <artifactId>postgresql</artifactId>
    <version>42.1.4</version>
</dependency>

または、Gradleプロジェクトの場合:

compile 'org.postgresql:postgresql:42.1.4'

6. CockroachDB を使用する

これで作業内容が明確になり、すべてが適切に設定されたので、使用を開始しましょう。

PostgreSQLとの互換性のおかげで、JDBCに直接接続することも、HibernateなどのORMを使用することも可能です。開発者に)。今回の場合は、JDBCを使用してデータベースとやり取りします。

簡単にするために、基本的なCRUD操作から順に説明します。

データベースに接続することから始めましょう。

6.1. CockroachDBへの接続

データベースとの接続を開くには、 DriverManager クラスの getConnection() メソッドを使用できます。このメソッドには、接続URL String パラメータ、ユーザー名、およびパスワードが必要です。

Connection con = DriverManager.getConnection(
  "jdbc:postgresql://localhost:26257/testdb", "user17", "qwerty"
);

6.2. テーブルを作成する

正常に接続されたら、すべてのCRUD操作に使用する articles テーブルの作成を開始できます。

String TABLE__NAME = "articles";
StringBuilder sb = new StringBuilder("CREATE TABLE IF NOT EXISTS ")
  .append(TABLE__NAME)
  .append("(id uuid PRIMARY KEY, ")
  .append("title string,")
  .append("author string)");

String query = sb.toString();
Statement stmt = connection.createStatement();
stmt.execute(query);

テーブルが正しく作成されたことを確認したい場合は、 SHOW TABLES コマンドを使用できます。

PreparedStatement preparedStatement = con.prepareStatement("SHOW TABLES");
ResultSet resultSet = preparedStatement.executeQuery();
List tables = new ArrayList<>();
while (resultSet.next()) {
    tables.add(resultSet.getString("Table"));
}

assertTrue(tables.stream().anyMatch(t -> t.equals(TABLE__NAME)));

作成したばかりのテーブルを変更することがどのように可能であるかを見てみましょう。

6.3. テーブルを変更する

テーブルの作成中にいくつかの列を見逃した場合、または後で必要になったために、簡単に追加できます。

StringBuilder sb = new StringBuilder("ALTER TABLE ").append(TABLE__NAME)
  .append(" ADD ")
  .append(columnName)
  .append(" ")
  .append(columnType);

String query = sb.toString();
Statement stmt = connection.createStatement();
stmt.execute(query);

テーブルを変更したら、 SHOW COLUMNS FROM コマンドを使用して新しい列が追加されたかどうかを確認できます。

String query = "SHOW COLUMNS FROM " + TABLE__NAME;
PreparedStatement preparedStatement = con.prepareStatement(query);
ResultSet resultSet = preparedStatement.executeQuery();
List<String> columns = new ArrayList<>();
while (resultSet.next()) {
    columns.add(resultSet.getString("Field"));
}

assertTrue(columns.stream().anyMatch(c -> c.equals(columnName)));

6.4. テーブルを削除する

テーブルを扱うとき、時々それらを削除する必要があり、これは数行のコードで簡単に達成できます。

StringBuilder sb = new StringBuilder("DROP TABLE IF EXISTS ")
  .append(TABLE__NAME);

String query = sb.toString();
Statement stmt = connection.createStatement();
stmt.execute(query);

6.5. データを挿入する

テーブルに対して実行できる操作が明確になったら、今度はデータの処理を開始できます。 Article クラスの定義を始めましょう。

public class Article {

    private UUID id;
    private String title;
    private String author;

   //standard constructor/getters/setters
}

これで、 articles テーブルに Article を追加する方法がわかります。

StringBuilder sb = new StringBuilder("INSERT INTO ").append(TABLE__NAME)
  .append("(id, title, author) ")
  .append("VALUES (?,?,?)");

String query = sb.toString();
PreparedStatement preparedStatement = connection.prepareStatement(query);
preparedStatement.setString(1, article.getId().toString());
preparedStatement.setString(2, article.getTitle());
preparedStatement.setString(3, article.getAuthor());
preparedStatement.execute();

6.6. データを読む

データがテーブルに格納されたら、それらのデータを読みたいので、これは簡単に達成できます。

StringBuilder sb = new StringBuilder("SELECT **  FROM ")
  .append(TABLE__NAME);

String query = sb.toString();
PreparedStatement preparedStatement = connection.prepareStatement(query);
ResultSet rs = preparedStatement.executeQuery();

ただし、 articles テーブル内のすべてのデータを1つの Article だけで読み取りたくない場合は、単に PreparedStatement の作成方法を変更できます。

StringBuilder sb = new StringBuilder("SELECT **  FROM ").append(TABLE__NAME)
  .append(" WHERE title = ?");

String query = sb.toString();
PreparedStatement preparedStatement = connection.prepareStatement(query);
preparedStatement.setString(1, title);
ResultSet rs = preparedStatement.executeQuery();

6.7. データを削除する

大事なことを言い忘れましたが、テーブルからデータを削除する場合は、標準の DELETE FROM コマンドを使用して限られたレコードセットを削除できます。

StringBuilder sb = new StringBuilder("DELETE FROM ").append(TABLE__NAME)
  .append(" WHERE title = ?");

String query = sb.toString();
PreparedStatement preparedStatement = connection.prepareStatement(query);
preparedStatement.setString(1, title);
preparedStatement.execute();

あるいは、 TRUNCATE 関数を使用して、テーブル内のすべてのレコードを削除することもできます。

StringBuilder sb = new StringBuilder("TRUNCATE TABLE ")
  .append(TABLE__NAME);

String query = sb.toString();
Statement stmt = connection.createStatement();
stmt.execute(query);

6.8. トランザクション処理

データベースに接続されると、デフォルトでは、各SQL文はトランザクションとして扱われ、実行が完了した直後に自動的にコミットされます。

ただし、2つ以上のSQLステートメントを単一のトランザクションにまとめることを許可したい場合は、トランザクションをプログラムで制御する必要があります。

まず、 Connection autoCommit プロパティを false に設定して自動コミットモードを無効にし、次に commit() メソッドと rollback() メソッドを使用してトランザクションを制御します。

複数の挿入を行うときにデータの一貫性をどのように達成できるかを見てみましょう。

try {
    con.setAutoCommit(false);

    UUID articleId = UUID.randomUUID();

    Article article = new Article(
      articleId, "Guide to CockroachDB in Java", "baeldung"
    );
    articleRepository.insertArticle(article);

    article = new Article(
      articleId, "A Guide to MongoDB with Java", "baeldung"
    );
    articleRepository.insertArticle(article);//Exception

    con.commit();
} catch (Exception e) {
    con.rollback();
} finally {
    con.setAutoCommit(true);
}

この場合、2回目の挿入で、主キー制約の違反に対して例外が送出されたため、 articles テーブルに記事は挿入されませんでした。

7. 結論

この記事では、CockroachDBとは何か、単純なローカルクラスタを設定する方法、そしてJavaからどのようにしてそれと対話できるかについて説明しました。

この記事の完全なソースコードは、いつものようにhttps://github.com/eugenp/tutorials/tree/master/persistence-modules/java-cockroachdb[over Github]で見つけることができます。