Upgrade to Pro — share decks privately, control downloads, hide ads and more …

immutable database

xorphitus
October 07, 2015

immutable database

Datomic の紹介です。

xorphitus

October 07, 2015
Tweet

More Decks by xorphitus

Other Decks in Programming

Transcript

  1. Datomic とは • CRUDのうち C と R しかない ◦ 一度作られたデータはイミュータブルである

    • 追記型 ◦ 変更は、同一 ID で新しいレコードを追加する ◦ ただし PostgreSQL と違って過去の履歴を全て保持 するモデル ◦ 削除は、同一 ID で打ち消しを意味するレコードを追加する • クエリは Datalog という Prolog のサブセット • プロプライエタリ というスペックなのだが、その背後には独自の論理モデルがある模様
  2. Datomic の思想 • これまでの DB は場所指向だった ◦ PLOP (Place-Oriented Programming)

    ◦ リソースが希少だった時代、新しい情報は、古い情報のあった場所に上書きすることで、空間 (ディ スクとメモリ) を節約する必要があった ▪ 情報は場所に紐付いた存在となった ▪ そして DB サーバは、場所の管理を頑張らないといけなくなった • いや、今そんな貧しい時代じゃねえし ◦ だいたい、ここでいう「場所」って情報と関係ない概念だよね ◦ あと、過去にあった情報、すなわちその時点における事実は変わらない ▪ 例えば、人間が引っ越しをしても過去の住所が UPDATE されるわけではない • 場所指向をやめたらかっこいいアーキテクチャにできるよ! ◦ いまここ
  3. 場所指向で何が悪い? • DB サーバの担ってる以下の責任を、一箇所で行う必要が出てくる ◦ トランザクション ◦ データ一貫性の維持 ◦ インデキシング

    ◦ ストレージの I/O ◦ クエリの受け付け • ディスクとメモリの何処に何があるか、を各々が把握して動く状態 ◦ PostgreSQL 的な追記型アーキテクチャでも上記は同じ場所に配置されていて問題解決していな い ◦ また、App から分断された世界が作られることでインピーダンスミスマッチが起きる • これらを分解したい ◦ 各々がシンプルになり、特定の処理に特化でき、好きな場所に再配置可能 ◦ (分散っぽい話になってきた )
  4. で、場所指向をやめる • 新しいデータは、一方的に蓄積していこう ◦ 一度積まれたデータの更新・削除はもう考えない ◦ 少し低いレイヤで起きていることは、 RDB でいう履歴テーブルみたいな状態 ◦

    富豪的な時代になったものである • こうした一方的なデータストレージに対し、それっぽい抽象 I/F つけたら諸々分離で きるんじゃね? ◦ …と、いうことなんじゃないかな ◦ 質問は受け付けません
  5. ちなみにデータモデルはこんな感じ • 田中さんの fact を追加 ◦ {id: 1, name: ‘田中’,

    address: ‘東京都渋谷区神南’} • 田中さんが引っ越したので fact をさらに追加 ◦ {id: 1, name: ‘田中’, address: ‘東京都神田錦町’} • で、2 レコードになる ◦ 最初の fact は immutable ◦ クエリでは、特に指定がなければ現在の fact が取得される ◦ 過去に遡って取得もできる
  6. Datomic のアーキテクチャ Peer, Strage Service, Transactor の 3つから構成される 詳細は後述するが Datomic

    は複数サービスの集積である • Storage Service はただデータを入れるだけ のサーバ • Peer は AP に組み込まれ、Storage Serivice からデータ取得をする • Transactor は上記2つから分離した、トラン ザクション処理専門部分
  7. Peer のお仕事 • App のプロセスに (ライブラリとして) 組み込まれて動作するもので • Query を処理して

    • Storage Service から該当するデータを取得し • App のメモリ内のキャッシュする ◦ 各 fact はイミュータブルからキャッシュし放題 ▪ キャッシュも背後のストレージも、 App からしたら意識することなく扱える • 一般的な RDB に対するメリット ▪ App のサーバを複数立てれば、 DB の Read 性能はスケールする ▪ ちなみに LRU ▪ この層に memcached を使うこともできるっぽい ◦ 新たな fact が積まれた場合、Transactor がそれを各 Peer にブロードキャストする (後述)
  8. Transactor のお仕事 • Write (追記) は全て Transactor (ぶっちゃけSPOF的) が Peer

    からの指示で担う ◦ Transactor は全ての処理をトランザクションとし、シリアルに行う ◦ なので Write 時にロックとらなくてもいいし、とってない • 何それ怖えー、となりそうだが、設計思想としては ◦ 他の処理は全部 Peer に寄せてるんだから Transactor クッソ軽い ◦ こいつ落ちても各 Peer は生きてるし Read は継続可能 ◦ Hot Standby 機を立ときゃいいわけだし ◦ そもそも Transactor が高負荷になるものに Datomic 使うのが間違いの元 ▪ 他の技術を使いましょう ◦ (あと、よく考えたら MySQL の Master だって似たようなもんだじゃね? ) • Write したら Peer にブロードキャストして Peer 内 Index を更新する
  9. Strage Service のお仕事 • ファイルシステムを抽象化して ◦ Peer にデータを提供する ◦ Transactor

    から書き込まれる • RDBMS や KVS (選択可能) が抽象化技術として使われる ◦ ファイルシステムに直接触ることはない
  10. Storage Service 層ってどうなってるの? Backend に MySQL を選択するとこれだけ… CREATE TABLE datomic_kvs

    ( id varchar(640) NOT NULL, rev integer, map text, val longblob, CONSTRAINT pk_id PRIMARY KEY (id) ) ENGINE=INNODB
  11. まとめのような何か • 旧来の RDBMS が一手に担っていた各部分が分散されるようになった • Write はシリアルに実行される ◦ 軽量な

    Transactor が順次実行する • Read は App に分散される ◦ App のプロセス内で積極的にキャッシュし、各 App のノードはそこから読み出す ◦ クエリ処理〜データ取得 (キャッシュヒットすれば ) が分散処理される