ブログ@nnaka2992

データベースってなんだよ

PGUnconf #46 でPostgreSQL の開発するときにまず何からすればいいかを聞いてきた

PGUnconf #46 でPostgreSQL の開発するときにまず何からすればいいかを聞いてきた

概要

2024年3月23日に第46回 PostgreSQLアンカンファレンス@東京が開催されました。

PostgreSQLアンカンファレンスは日本PostgreSQLユーザー会が主催するイベントでPostgreSQLユーザーはもちろん、 PostgreSQLのコントリンビューターやコミッターも参加しているイベントです。

その中でPostgreSQL メジャーコントリビューターであり、コミッターでもある@masahiko_sawadaさんが、PGConn 2024MAKING POSTGRESQL HACKING MORE INCLUSIVEというセッションでPostgreSQLコミュニティーがどうすればより初心者にオープンになれるか? という内容でディスカッションするそうです。

そこに向けてアイデアはあるか? 困ってることはないか? という相談? をされていました。

経験豊富な方々は実践的な案を出していましたが、私はPostgreSQLにコードコントリビュートしたいけど何からすればいいのか分らないという状態だったのでこの機会に相談してみました。

自分のレベル感

何が分からなかったのか?

そもそもPostgreSQLメーリングリストとパッチの文化なのでGitHub/Labなどになれた身からするとよく分からないです。 またGitHubで管理されているOSSでは良くあるgood first issueのようなものも存在しないため、新規参入者には難しいと感じていました。

なにからすればいいのか?

PGUnconfでは以下のようなアドバイスを受けました。

  1. チュートリアルをなぞってドキュメント通りに動かないものを修正する
  2. 初心者向けコンテンツへの追記は初心者にしか出来ないので、是非おねがいしたいとのことでした
  3. 既存のパッチで放置されているもの(Headでビルドできないようなもの)をアップデートする
  4. メーリングリストのディスカッションを眺めてネタを探す
  5. 新規機能を試してバグをさがし、修正する
  6. CommitFestに参加する

まとめ

1のネタを探してみつつ、PostgreSQL17のリリースが近いので4に取りくんでみようと思います。

2023年の振り返りをする

みんな振り返りしてる。振り返りしてないのはお前だけ。

なので振り返りします。

登壇関係

2023-06-22 3-shake SRE Tech Talk #6

これまで対外向けの登壇は行なったことが無かったのでこれが登壇デビューでした。

DBREノススメ

所属会社である株式会社スリーシェイクの主催するイベントでしたが、一度登壇すると登壇のハードルが低くなるのでとてもいい機会でした。

今の会社にDBREerポジションで入社して6か月目の登壇なので今見ると当時と違う意見の部分もあったりしますが、今もDBREもSREも何なのか分かりません。

2023-09-26 YugabyteDB Japan Meetup #3

別件でYugabyte Japanの方と話していたところ、登壇してみないか? と誘われたためホイホイ話しに行った登壇でした。

紹介 データベース信頼性エンジニアリング

SRETTの方ではSREの存在を認知している方が多いだろうと想定して何故DBREが必要なのか? という話しをしたのに対して、 こちらではDB関係者が多いと想いDBAとDBREという切り口で発表しました。

YugabyteDBはドキュメントを始めから読む活動をしていたり(2023年後半はあまり出来ていませんが)、ローカル環境で動かして遊んだりは していたもののYugabyteDBについて話せるほどの理解は(今も)なく次にYugabyteDB Japan Meetupで話す機会があればYugabyteDBについてを 主題に話したいと思いました。

2023-10-12 3-shake SRE Tech Talk #7

6月の登壇と同様に所属会社主催のイベントでした。

KubernetesでDBを動かしたい

2021年ごろにDBをKubernetesで動かす記事見て以来DB on Kubernetesには興味があったのですが、Kubernetes自体やデータベースのお勉強を していたらなかなかDB on k8sまでたどりつけていませんでした。

それをイベント駆動で無理やり勉強したのがこのイベントでした。

内容としてはありきたりですが、Zalando Postgres Operatorを動かしましたというだけのものですが、ここでDB on k8sを さわってからはいろいろな機会でDB on k8sを触るようになりました。

2023-12-26 第44回 PostgreSQLアンカンファレンス@オンライン

年内最後の登壇はPostgreSQLアンカンファレンスでした。

pgrollで実現するスキーマブルーグリーンデプロイメント

ちょうど登壇しやすいネタを抱えてたのとアドベントカレンダーでそーだいさんが運用・開発よりの話しが足りないと書いていたのを見て、 DBREを名乗っているし話さなきゃいけないだろと思ったので登壇しました。

もっと運用よりだったりサービス開発だったり設計よりの話も募集中です。 大体そういうの喋る担当が自分だけなのでめちゃめちゃ需要があるので気軽にどうぞ。

登壇自体はpodman-composedocker composeの差分で悲しいライブデモになりました。 検証環境と登壇環境はそろえなきゃいけないなと思いました。

ブログ関連

はてなブログでは主に読んだ論文やドキュメントについてまとめ、zennでは何かを調べてまとめたものや 検証した結果をまとめるように使い分け運用しました。

はてなブログでやっているYugabyteDBのドキュメントを全部読む取り組みは途中で止ってしまっているので動かします。

zennの方は社内向けに話すもののうち社外に出しても問題ないようなものを垂れ流していましす。2024年は技術検証方面に力をいれたいので zennを活発に出来たらなと思います。

アドベントカレンダーは大風呂敷で畳みきれなかったデータベースエンジニアのためのDB on Kubernetes入門ガイドに始まり、誰得なのかわからないAlloyDB omni on Kubernetesを眺めると続いて、sqldefとpgrollを利用したPostgreSQLでのスキーマブルーグリーンデプロイメントを書きました。

ターゲットは誰だったんですかね?

まとめ

2023年は今までインプット重視だったところからアウトプットを考えだした年でした。

これはそろそろアウトプットをしなきゃいけないという思いもあったものの、2023年1月に現職に転職し社外へのアウトプットをする人が 多くいたからという面も多大にあります。

人は周りの5人の平均になるという言葉があるらしいですが、まさしくその例で環境が変り周りの人が変ったため個人の方向性も変ったのではないかと思います。

外部にアウトプットすることが偉いわけではありませんが、外部に発信すると新しい機会も産まれましたし1来年以降も継続していきたいです。


  1. YugabyteDB Japan Meetup #3がその典型でした。

YugabyteDBのドキュメントを全部読む Day9

前回からつづいてYugabyteDBのドキュメントを読んでいきます。

前回はArchitecture > Core functions > Read I/O pathを読みました。 今回はArchitecture > Core functions > High Availabilityを読みます。

ドキュメントのバージョンは最新のv2.19 previewです。 また画像は同ドキュメントより引用しています。

High availability

YugabyteDBは一貫性と分断耐性を兼ね備えたデータベースであると同時にリーダーの障害時に新しいリーダーとして フェイルオーバー出来るアクティブレプリカを持つことで高可用性(HA)を達成している。

もしノードに障害が発生した場合、そのノード上で動作するYB-TServerとYB-Masterの停止を引き起こす。

YB-TServer failure

YB-TServerはYSQLレイヤとアクティブなIOを提供するピアーリーダータブレットを含むタブレットをホストする。

YSQレイヤとタブレットピアーフォロワーとタブレットピアーリーダーで発生した障害はそれぞれ特別な方法で あつかわれる。

YQL failure

アプリケーションの視点からみればYQLはステートレスである。そのためクライアントが発行したリクエストは単純に他ノードのYQLに リクエストが送信される。スマートクライアントを利用している場合、スマートクライアントは理想的なYB-TServerの場所 をタブレットが所有するキーから検索し、リクエストを直接そのノードに転送する。

Tablet peer follower failure

タブレットピアーフォロワーはクリティカルパスではない。この障害はユーザーリクエストへの可用性に影響しない。

Tablet peer leader failure

タブレットピアーリーダーの障害は数秒以内にRaftレベルのリーダー選出を自動的にトリガーし、他のYB-TServerに配置されている タブレットピアーが新しいリーダーとして選出される。 タブレットピアリーダーに障害が発生した場合、可用性が損なわている時間は約3秒(ハードビートの感覚がデフォルトの500msの場合)である。

YB-Master failure

YB-Masterは通常のIOオペレーションではクリティカルパスでは無いため、ユニバースを動作させるのに影響は無い。 しかしYB-Masterは異るノードで動作するピアーのRaftグループの一部であるため。 このピアーのうちの一つがアクティブなマスターで残りがアクティブスタンバイである。 YB-Masterのリーダーであるアクティブマスターに障害が発生した場合、ピアーはリーダーの障害を検知し、新なアクティブ マスターであるYB-Masterのリーダーを障害時に数秒以内で再選出する。

YugabyteDBのドキュメントを全部読む Day8

前回からつづいてYugabyteDBのドキュメントを読んでいきます。

前回はArchitecture > Core functions > Write I/O pathを読みました。 今回はArchitecture > Core functions > Read I/O pathを読みます。

ドキュメントのバージョンは最新のv2.19 previewです。 また画像は同ドキュメントより引用しています。

Read I/O path

I/O Pathはタブレットリーダーが特定されリード処理を実行する単一キーの例で説明することが出来る。

Tablet leader identification

ユーザーが発行したYQLクエリレイヤに作用するリードリクエストはポートから適切なAPI(YQLまたはYCQL)を経由して行なわれる。 このユーザリクエストはYQLレイヤで内部キーに変換され、YQLレイヤがタブレットとそれをホストするYB-TServerを発見するのに利用される。 YQLレイヤはこれをYB-MasterにたしてRPC呼び出しを実行するために行なう。 またそのレスポンスは将来の利用のためにキャッシュされる。 その後YQLレイヤはリーダータブレットピアーをホストするYB-TServerに対してリード処理を行なう。 このリード処理は内部キーを保持するタブレットのRaftグループのリーダーによって処理される。 このリードリクエストを処理するRaftグループのリーダーはDocDBから読み込みを実行し、その結果をユーザーに戻す。

Write I/O Pathで説明した通り、 YugabyteDBのスマートクライアントではアプリケーションのリクエストを直接適切なYB-TServerに送信することが出来るため、 余計なネットワークホップやマスターへのアクセスを省略することが出来る。

Read operation performed by tablet leader

kという値をKというプライマリキー行に持つテーブルT1からデータを取得するケースについて考える。 またテーブルT1はキー行Kと値行Vを持つものとする。1

下記の画像はリード処理について説明している。 read_path_io

YugabyteDBはデフォルトでは強整合性の読み取りを採用している。

リードクエリはさらに複雑になることもある。YQLクエリレイヤーは式やビルトイン関数、算術演算を含むクエリを処理するfully-optimized2されたクエリエンジンを持っている。


  1. SELECT K,V from T1 where K = 'k'ということ
  2. fully optimizedってよくいうけど完全に最適化されたって書くと完全ってなんだってなる

YugabyteDBのドキュメントを全部読む Day7

前回からつづいてYugabyteDBのドキュメントを読んでいきます。

前回はArchitecture > Core functions > Table Creationを読みました。 今回はArchitecture > Core functions > Write I/O pathを読みます。

ドキュメントのバージョンは最新のv2.19 previewです。 また画像は同ドキュメントより引用しています。

Write I/O path

Write I/O pathはYQLレイヤーで処理され、タブレットリーダーによってレプリケーションの準備が行なわれる シングルキーでの書き込みとして例示することが出来る。

アトミックなアップデートを共なう複数キーでの分散トランザクションなど複雑なケースについては 分散トランザクションに記載する。

Write operation processing by YQL layer

ユーザーが発行したYQLクエリレイヤに作用するライトリクエストはポートから適切なAPI(YQLまたはYCQL)を経由して行なわれる。 このユーザーリクエストはYQLレイヤで内部キーに変換される。 シャーディングで説明するように、 それぞれのキーは一つのタブレットが所有する。 どのタブレットがキーを所有するか特定するために、YQLレイヤはYB-MasterにRPC1呼び出しを実行する。 そのレスポンスは将来の利用のためにキャッシュされる。

YugabyteDBはタブレットの場所をキャッシュし直接参照することでネットワークホップを減らすことで、YQLレイヤが直接適切なYB-TServerにホストされるタブレットリーダーにリクエストを送信することが出来るスマートクライアントを持つ。 YQLレイヤがローカルノードにタブレットリーダーを見つけた場合、RPCはローカルファンクションコールになりリクエストをシリアライズとデシリアライズしてネットワーク越しに送信する時間を節約することが出来る。

その後YQLレイヤはタブレットリーダーをホストするYB-TServerへの書き込みを発行する。 この書き込みはキーを所有するRaftグループのタブレットリーダーによって処理される。

Preparation of the operation for replication by tablet leader

下記の図はタブレットリーダーがレプリケーションを実行する処理を説明している。

single_shard_txns_insert_if_not_exists

タブレットのRaft Groupリーダーは以下の処理を実行する。

  1. 現在実行されている処理が現在のスキーマに対応しているかを判別する
  2. キーに対してローカルin-memoryロックマネージャーを利用してロックを取得する。このロック機構はフォロワーには存在しない
  3. 必要であればデータを読み込む(read-modify-writeや条件付きアップデート命令など)
  4. DocDBに書き込まれる変更のバッチを準備する。この書き込みバッチは殆ど最終的にRocksDBに書き込まれるKey-Valueペアに近く、それぞれのキーの末尾に最終的なhybrid timestampが添えられていないだけである

Raft replication of the write operation

書き込みのRaftレプリケーション処理の流れは以下のように説明することが出来る。

  1. リーダーがバッチをRaft logにアペンドし、書き込みのためのhybrid timestampを選択する
  2. Raftを利用しデータをピアーに複製する
  3. 成功したRaft replicationのデータをローカルのDocDBに反映する
  4. ユーザーに成功を返す

フォロワータブレットはRaftを利用したデータの複製を受けつけ、コミットされた事が分ったタイミングでその複製をローカルのDocDBに反映する。 リーダーは以下のようにコミットポイントに於ける後続のRPCリクエストの進行を進める。

  1. 書き込みバッチを含むRaftエントリーは過半数以上のタブレットRaft Groupピアーに複製される
  2. Raftのサブシステムから"Replication Successful"のコールバックを取得したあと、リーダーはローカルのDocDBにバッチの書き込みを適用する
  3. リーダーからの次の更新でエントリーがコミットされたことがフォロワーに通知され、フォロワーはそれぞれのRocksDBインスタンスにバッチの書き込みを適用する。

Response to the client

Information Pending2

Examples

kvという値をKという行とVという行をもつテーブルT1に挿入する例について考える3

write_path_io

この例ではユーザーアプリケーションがランダムなYugabyteDBサーバにWriteクエリを送信し、そのサーバがリクエストを適切にルーティングすると仮定して簡略化している。

特にYCQLではYugabyteDB Smart Clientを使うことで、余分なネットワークホップを避けることが出来る。


  1. Remote Procedure Call
  2. 原文ママ。過去のバージョンでも記載無し
  3. INSERT INTO T1 (K,V) VALUES('k','v')ということ

YugabyteDBのドキュメントを全部読む Day6

前回からつづいてYugabyteDBのドキュメントを読んでいきます。

前回はArchitecture > Core functions > Universe creationを読みました。 今回はArchitecture > Core functions > Table Creationを読みます。

ドキュメントのバージョンは最新のv2.19 previewです。 また画像は同ドキュメントより引用しています。

Table Cration

YugabyteDBではユーザーにより実行されるテーブルの作成はYB-Masterのリーダーが実行する非同期APIによって管理される。

YB-MasterはそのAPIでテーブルのスキーマと障害耐性を高めるために形成するRaftグループに所属するYB-Masterでのテーブル作成に 必要な他の情報のレプリケーションが完了した段階でAPIの成功を返す。

YB-Masterのリーダーがテーブル作成を実行するときは複数のステップが存在する。

Validation

YB-Masterリーダーはテーブルスキーマの検証を行ない、指定された数のタブレットを作成する。

これらのタブレットはこの段階ではYB-TServerには割り振られていない。

Replication

YB-MasterリーダーはYB-MasterのRaftグループにテーブルスキーマと新しく作成された タブレット(この時点ではYB-TServerへの割り当て行なわれていない)の複製を行なう。

この処理はYB-Masterリーダに障害が発生してもテーブル作成が成功することを保証する。

Acknowledgement

テーブル作成処理はYB-Masterリーダーに障害が発生しても処理を継続することが出来るため、この段階で非同期テーブル作成APIは成功を返す。

Execution

YB-Masterリーダーはそれぞれのタブレットレプリケーションファクターとして指定された数だけYB-TServerに割り当てを行なう。

このタブレットピアーの配置は指定された障害耐性を実現でき、またタブレットの割り当てがYB-TServerに均等に行なわれるように実行される。

タブレットのYB-TServerへの割り当てはタブレットのレプリカが複数クラウド、リージョン、アヴェイラビリティゾーンをまたいで分散するといった 追加の制約を満す必要がある。

Continuous monitoring

YB-Masterリーダーは全てのタブレットの割り当て処理を監視し、その実行状態と完了をユーザーが実行したAPIコールに対して応答する必要がある。

Examples

テーブルが4ノードからなるYugabyteDBUniverseに作成される処理について考える。 このときテーブルは16のタブレットと3つのレプリケーションファクターを持つとする。

  1. YB-Masterリーダーはスキーマを検証する。また16タブレット(合計48のタブレットピアー)を作成し、 Raftを利用して過半数のYB-TServerにテーブルの作成に必要なデータを複製する。 Create Table Masters
  2. 作成したタブレットをRaftグループを成すYB-TServerの中の指定された数のYB-TServer割り当て、リーダーの選出を行なう。 Tserver Tablet Assignment このタブレットに属するキーに対する全てのリードとライトは、タブレットピアーのリーダーとRaftグループが責任を持つ。
  3. タブレットが割り当てられると長期に渡る障害か将来のロードバランシングが発生しYB-Masterにオーナーシップを変更されるまで、 割り当て先のYB-TServerが所有する。 Table Peer Raft Group タブレットリーダーをホストするYB-TServerの内の1台に障害が発生した場合、タブレットのRaftグループはI/Oを処理するために 即座にリーダーエレクションを実行する。 そのためYB-MasterはI/Oにおけるクリティカルパスになることはない。
    YB-TServerが長時間に渡り障害状態にある場合、YB-Masterはデータのレプリケーション先となる候補を探す。 この複製処理は段階的かつGracefulに実行される。

YugabyteDBのドキュメントを全部読む Day5

前回からつづいてYugabyteDBのドキュメントを読んでいきます。

前回はArchitecture > Key Concepts > YB-Master serviceを読みました。 今回はArchitecture > Core functions > Universe creationを読みます。

ドキュメントのバージョンは最新のv2.19 previewです。 また画像は同ドキュメントより引用しています。

Universe creation

YugabyteDBのユニバース作成は複数のステップを含む。

Start YB-Masters

YBユニバース作成の最初のステップはレプリケーションファクターで指定された数だけYB-Masterを作成することである。 作成されたYB-Masterはそれぞれを認識している。

YB-Masterはユニバース内でユニークなID(UUID)をそれぞれに割り当て、それぞれを認識しあったあとにリーダーエレクションを実行する。

このステップの終りにYB-Masterの中のひとつがリーダーとして確立される。

Start YB-TServers

ノードの数だけYB-TServerを起動し、それぞれにマスターのアドレスを渡す。

それぞれのYB-TServerはマスターにハートビートを送信し、正常に動作していることを確認する。

ハートビートはYB-TServerが現在ホストしているタブレットとその負荷情報についても通信するが、この時点ではタブレットにデータは登録されていない。

Examples

4ノードからなるYBユニバースにテーブルを作成する場合について考える。テーブルのレプリケーションファクターは3とする。

  1. 3つのマスターがcreateモードで起動される。これはマスターがすでに起動しているために発生するエラーを防ぐために明示的に実行される。 create_universe_masters
  2. リーダーエレクションを実行し、リーダーを選出する。 create_universe_master_election
  3. YB-TServerが起動し、全てのYB-TServerがマスターにハートビートを送信する。 create_universe_tserver_heartbeat