ことはじめ

HTAPワークロード向けのデータベースとしてcockroach dbが有名。最近新たにtidbというのが台頭してきた。 個人的にOLAPとOLTPの両方のワークロードを効率よく捌くことに興味があるのでいろいろと調べてみる。

データベースの基本をまとめる

データベースの基本用語説明

  1. トランザクション 一連の処理をまとめたもの。一連の処理単位でコミット(確定)もしくはロールバック(破棄)する。この、一連の処理単位でコミットするかしないかを決めるのが大事。例えば、次のような処理を考える。 トランザクション開始ー>在庫テーブルで保持している商品の在庫を減らす ー> 注文テーブルに購入者情報を登録 ー> トランザクション終了

ここで、ステップ2で在庫テーブルで保持している商品の在庫を減らした後、ステップ3でエラーが発生したとする。 この時、この一連の処理がトランザクション処理として扱われている場合は、エラー発生後、処理開始前までロールバックすることが可能である。 しかし、トランザクション処理がない場合は、ステップ2だけが実行され、一貫性のないデータになってしまう。こういったことを防ぐために「トランザクション処理」が必要となる。

Mysqlで実際にトランザクションを実行するためのSQLを下に示す。

mysql> BEGIN;
Query OK, 0 rows affected (0.01 sec)

mysql> UPDATE `users` SET `name` = "xxx" WHERE `id` = 1;
Query OK, 1 row affected (0.00 sec)
Rows matched: 1  Changed: 1  Warnings: 0

mysql> ROLLBACK;
Query OK, 0 rows affected (0.00 sec)

Beginでトランザクションが始まる。最後にROLLBACKしているからこれは破棄される。

mysql> BEGIN;
Query OK, 0 rows affected (0.00 sec)

mysql> UPDATE `users` SET `name` = "xxx" WHERE `id` = 1;
Query OK, 1 row affected (0.00 sec)
Rows matched: 1  Changed: 1  Warnings: 0

mysql> COMMIT;
Query OK, 0 rows affected (0.00 sec)

これは最後にCOMMITされているので変更が永続化されるわけですね。 ちなみに、BEGINの代わりにSTART TRANSACTIONで初めてもいいです。

  1. ストレージエンジン(!=データベースエンジン) ずっと間違えていた。データベースのフロントエンドとディスクの間のプログラム。ミドルレイヤっていうのかな?

SQL文を受け取って結果を返すデータベースエンジン部分 ⇨ つまりテーブルにデータを書き込んだり読みだしたりするプログラム 複数の種類があり、データの取得方法、保存方法、処理方法がストレージエンジンによって異なる MySQLの場合、テーブル毎にストレージエンジンを分けられる

  1. タプル = レコード

  2. インメモリDB データをメモリ上で格納するように設計されているデータベース。レスポンスタイムを姑息かするのが目的。

  3. ACID トランザクション処理において必要とされる4つの要素、 Atomicity, Consistency, Isolation, Durabilityの頭文字。 日本語になおすと、それぞれ、原始性、一貫性、独立性、永続性である。それぞれ説明していきたいと思う。

Atomicity : トランザクション処理が「すべて実行される」もしくは「まったく実行しない」

Consistency : トランザクションの終了状態にかかわらず、データベースの整合性が保たれていること

Isolation : トランザクションを複数同時に実行しても、単独実行の場合と同じ処理結果にならなければいけない。<ー これが難しいのよ。かなり難しいのよ。完全にロックしてしまえば一貫性を保てるのだけど、性能が出ない。つまり、性能と一貫性のトレードオフが生じるって話ね。(トレードオフはネタになりやすいのよね) トレードオフでどっちを優先させるかってのが実はMySqlで決められるパラメータになっている。それを、トランザクション分離レベル (Transaction Isolation Level) という。全部で4つのレベルがある。

参考文献

Durability : トランザクションの更新結果は、障害が発生してもデータベースから失われてはいけない。

  1. OLAP = OnLine Analitical Processing wiki

OLTPデータベースは行ベースのストレージエンジンを利用。一方、OLAPはカラム型(列指向型)のデータベースを使用。 なぜか?OLAPはデータベースのすべてのデータを使ってなにか結論を出したり統計情報を出したりするから。そのため、列ごとにデータを持っていた方がいろいろとやりやすいって話ね。一方OLTPはトランザクション処理であり、トランザクションで変更されるデータはせいぜい数行のため、行単位で処理を行えばいい。

カラム型データベースについて カラム型データベースは列を抜き出して操作する集計処理などが得意。 一方、一般的な行指向のデータベースは追加更新削除のようなオンライントランザクション処理が得意。 これはデータのストア方式に起因するのかな? つまり、ディスク上のメモリ配置がカラム型だと列が連番?連番だと読み込みやすいって話があったよね?

列方向にデータを見ていくと、データ型が揃っていることもあって値が似ていたり、同じ値が繰り返し表れることがよくあります。そのために列方向のデータは非常に圧縮効率が高いのです。

行指向データベースはおそらくデコードが連番でディスクに保存されている。この時、データ型が違う各型がメモリ上で隣に並ぶので、パディングの関係で圧縮効率が悪いってことなのかな?

ちなみに、よく聞くCassandraも列指向のデータベース。

  1. OLTP = OnLine Transaction Processing oracle

  2. HTAP = PingCAP HTAPデータベースはOLTPワークロードとOLAPワークロードの両方を処理するデータベース。

  3. 同時実行性 排他制御のこと

  4. MVCC (=マルチバージョン同時実効制御)

  5. シャーディング

シャーディングとは、データベースの負荷分散の手法の一つで、一つの表(テーブル)を複数の物理コンピュータに分割して記録する方式。

シャーディングについて

  1. キーバリューストア

一意のキーに値を対応付けて保存するデータ構造は多くプログラミング言語で連想配列、辞書(ディクショナリ)、ハッシュ、マップなどの名称で提供されてきており、KVSはこの仕組みを永続的なデータ管理システムに応用したものと考えることもできる。

この説明が一番しっくりと来ますね。

  1. noSQL noSSQL = RDB以外のデータベース。 どんな種類があるか? noSQLの種類について キーバリューストア =! カラム指向

  2. CAP定理

NoSQLとRDBの特性の違いを説明する上で重要な「CAP定理」という定理があります。 分散型データベースシステムにおける三大要件として以下が存在します。

Consistency(整合性)…常に同一のデータを参照する Availability(可用性)… 常に読み出しと書き込みができる Partition Tolerance(分断耐性)…ネットワークが分断されても間違った結果を引き起こさない 分散型データベースシステムでは、上記の3つのうち最大2つしか満たすことができない、というのがCAP定理です。

  1. 分散KV 分散キーバリューストア型のデータベース。 TIDBで使われているのはこのストレージエンジンです。

  2. クエリエンジン フロントエンドのことかな?

  3. 楽観的/悲観的な排他制御 qiitaの記事

楽観ロックと排他ロックの二つがある。 どちらともデータの整合性をとろうという目的で入るのだが、楽観ロックはmutexを使っていないからデータの不整合が生じる可能性があると思っている。Leoのインターン生が言っていたのはこれのこと。ソフトウェア的にカウンター(バージョン管理のキー、これをロックキーという)を管理して、読み込んだ時のカウンターと書き込もうとしているときのカウンターが違かったらトランザクションをロールバックしてもう一回最初からになる。セマフォっていうのはこれのことなのか?

  1. オンライン処理とバッチ処理 記事 時間がかかるのがバッチ処理。すぐに終わるのがオンライン処理。 Hadoopはバッチ処理。Sparkはオンライン処理。

まず基本的にはOLTPとOLAPは混ぜたくない。しかし、 TIDBを使うことでRDBでもオンライン処理が可能になる? TIDBはRDBと見せかけた分散KV型のDBMSなのか? KVだから早いってことでいいのかな? まあ、一回、CMUのデータベース講座を受けないと話が始まらないな。

  1. RAFT

Raft は安全な State Machine Replication (SMR) を実装するための分散合意アルゴリズム。分散システムにおいて一貫性 (分散トランザクション) と可用性 (障害耐性) を実装するための基本的な部品として使用することができる。

分散合意アルゴリズム。

  1. ビザンチン将軍問題 wiki

こういう問題を解決する手法としてRAFTが存在する。

  1. transaction isolation levelの変更と生じる問題について ref

  2. newSQL RDBとnoSQLのいいところどりをしたデータベース。 RDB : トランザクションは得意だが、スケーラビリティーと高可用性を提供できない。 noSQL : キーバリューストアにより、高いスケーラビリティーを持つが、トランザクション処理に対応していない。 newSQL : トランザクションとスケーラビリティーを両立する、新しいデータベース。CockroachDBやGoogleSpannerはNewSQLらしい。

  3. セマフォ ミューテックスとの違いが知りたい。俺の理解では、ミューテックスはシステムコールでコンテキストスイッチが生じるからオーバーヘッドが大きい。 一方、セマフォはもうちょっとソフトウェア的な制御だから、完全にはatomicityを保証できないのではないか?というのが僕の今までの理解。間違っているかもしれない。ちなみにセマフォの考案者はダイクストラさん。

でも僕の理解は間違っていたみたい。

Yes, semaphores require system calls except in very special scenarios. A semaphore has to be able to wait for the other contenders to free the resource.2017/03/09

だそうです。ありがとうございます。

ストレージエンジンの例

  1. Leo : Yahooが開発している不揮発性データベースを用いたストレージエンジン
  2. InnoDb : Mysqlではデフォルトでこれが各テーブルのストレージエンジンになる。行ロック、トランザクション機能、堅牢性が高い。
  3. MyISAM : InnodDBとよく比較されるらしい。テーブルロックをする。アクセスが早い。トランザクション機能がない、InnoDBよりテーブルサイズが小さい、らしい。
  4. Memory : インメモリデータベースを実現する。mysqlを再起動するとデータが消えてしまう。メモリ上にあるため、アクセスが非常に高速である。
  5. 他にもたくさんあるわけですが。まあいいでしょう。有名どころだけ抑えておきましょう。ここに新しいストレージエンジンを追加するのが僕の仕事になるわけですね。

参考文献 はてな

その他、大事そうな知識を箇条書き

  1. システムコールではコンテキストスイッチが発生する。これは知らなかった。
  2. Mysqlはテーブル単位でストレージエンジンを選択することが可能。

参考文献

Mysqlのストレージエンジンについて MySQLについてまとめた

Tidb関連の用語説明

Tidb : MySQL互換のNewSQL NewSQL : 分散SQLデータベース OLAP : On LIne Analitical Procedure Tidb : ストレージエンジンのこと TiKV :

分散合意アルゴリズムRaftについて

参考文献

データベースのベンチマーク

  1. HammerDB
  2. sysbench
  3. tpc
  4. apb-1.Olap-bench
  5. OLAP_council

おもったこと。

目的に適したストレージエンジンを用いるべきであると感じた。 InnnoDBを使わないくていいところでは使わなかったり、そういうところ。 例えば、今作っている競馬システムはInnodbがいいのか?とかそういうこと。

参考文献

zen LINEのデータベースエンジニアのインタビュー

Hadoop関連の記事

2011年の記事

TiDB関連の面白そうな記事

  1. 1
  2. innodbの実装について

TiDBの良さを知るにはやはりOLTPとOLAPの両方を同時にやるようなアプリを作るのがいいと思った。

  1. 競馬システムは確かにOLTPとOLAPの融合だね。ただ、なんか少ないのよね。扱うデータの量が。ということで、株を始めないとだめだなと思った。はい、株始めましょう。 株を始めるにあたり、株価をどっかからとってこないとだめなんですよね。 それがこちらになります。

株情報API

まとめると

  1. RDBは行指向型のデータベースでトランザクション処理(OLTP)が得意
  2. KVSやカラム指向型のデータベースは列単位でのアクセスが高速にできるため、集計処理等のOLAPが得意
  3. 従来のシステムでは、RDBをトランザクションに用いて、RDBのコピーを定期的に別のデータベースに移して、そのコピーのデータをHadoop等を用いて解析していた。 そのため、解析等で得られる結果は鮮度の低い結果となっていた。
  4. しかし、近年は鮮度が重要になるケースが増えてきている。つまり、OLTPとOLAPが同時にできるシステムが重要となってきている。
  5. そこで、開発されたのがTIDBである。
  6. TidbはMysqlのインターフェースを提供(つまり、RDB)でありながら、内部ではKVSでデータを保持する為、トランザクション処理が可能でありながら、高速なanalitical処理を可能にする。

解消しない疑問

  1. トランザクション処理が行われているときに、リードもロックによって停止されてしまうのか?そこは気になる。
  2. selectは結局どこでselectしているのか?ディスクから一回メモリに持ってきているのか?それともディスクからそのまま探しているのか?

andy pavlo氏のキーノート

その他データベース関係で注目すべき記事

クエリオプティマイザに機械学習を適応しているMySQL Autopilot HPC DATABASEだってさ Analiticalな処理を高速化するための手段として、インメモリデータベースやcolumnarデータベースや、high performance SQL、short execution pathがある。しかし、このすべてが整っているデータベースを見つけるのは難しい。そして、これらの手段を提供していても、トランザクションを実行するためのacidをサポートしていないものも多い。そこで、トランザクションをサポートしつつ、高速化も行ってしまう eXtremeDB HPCってのがあるらしいんだけど。わたくしがこれを超えるデータベースを開発して差し上げましょう。 ただ、上の奴は開発時に役立つかもしれないね。 2020年のNEWSQLの動向 pmemを使ったストレージエンジンの研究 buffer poolとかの情報を見る方法 msyql profile mysql profiler2