2016年の冬休み。
Hadoop
dnf インストールする。他にもいろいろ、入る。
# dnf install hadoop-client hadoop-common hadoop-hdfs hadoop-mapreduce hadoop-mapreduce-examples hadoop-yarn
こういうアカウントが追加される。
hsqldb
derby:Apache Derby service account
zookeeper:ZooKeeper service account
hdfs:Apache Hadoop HDFS:
mapred:Apache Hadoop MapReduce
yarn:Apache Hadoop Yarn
定義ファイルはここに置かれる。デフォルトで、1台でHDFSを使う設定になっている。
$ pwd
/etc/hadoop
$ cat core-site.xml
自分のホストのHDFS を使う。
<name>fs.default.name</name>
<value>hdfs://localhost:8020</value>
$ cat slaves
localhost
$ more hdfs-site.xml
複製は一つ。
<name>dfs.replication</name>
<value>1</value>
HDFSの実体はこの下に置かれる。
<name>hadoop.tmp.dir</name>
<value>/var/lib/hadoop-hdfs/${user.name}</value>
<name>dfs.namenode.name.dir</name>
<value>file:///var/lib/hadoop-hdfs/${user.name}/dfs/namenode</value>
<name>dfs.datanode.data.dir</name>
<value>file:///var/lib/hadoop-hdfs/${user.name}/dfs/datanode</value>
めんどうなので、ルートで動かす。一般ユーザを使うなら /var/lib とかの権限を与えるか、別ディレクトリにするか。
# hdfs namenode -format
# start-dfs.sh
# start-yarn.sh
# jps
31443 Jps
30708 SecondaryNameNode
30505 DataNode
31082 NodeManager
30330 NameNode
30975 ResourceManager
50070 ポートで、ブラウザアクセスできる。
ファイルシステムに書き込んで、 map reduce
# hdfs dfs -df
Filesystem Size Used Available Use%
hdfs://localhost:8020 53660876800 4096 48435568640 0%
# hdfs dfs -put /etc/services /
# hdfs dfs -ls /
Found 2 items
-rw-r--r-- 1 root supergroup 681813 2016-12-26 09:15 /services
drwx------ - root supergroup 0 2016-12-26 09:11 /tmp
# hadoop jar /usr/share/java/hadoop/hadoop-mapreduce-examples.jar wordcount /services /out
16/12/26 09:19:25 INFO mapreduce.Job: Counters: 49
File System Counters
FILE: Number of bytes read=349388
FILE: Number of bytes written=886895
..
結果はここに書かれる。
# hdfs dfs -ls /out
Found 2 items
-rw-r--r-- 1 root supergroup 0 2016-12-26 09:19 /out/_SUCCESS
-rw-r--r-- 1 root supergroup 255545 2016-12-26 09:19 /out/part-r-00000
# hdfs dfs -cat /out/part-r-00000
"wnn4" 1
# 11130
### 2
..
JobTracker は、 yarn になって、 8088 ポートで、ブラウザアクセスできる。
ファイルの実体はこのへんにできる。
# pwd
/var/lib/hadoop-hdfs/root/dfs/datanode/current/BP-2128698733-127.0.0.1-1482709440886/current/finalized
# ls -l
-rw-r--r--. 1 root root 681813 12月 26 09:15 blk_1073741827
-rw-r--r--. 1 root root 5335 12月 26 09:15 blk_1073741827_1003.meta
-rw-r--r--. 1 root root 255545 12月 26 09:19 blk_1073741834
-rw-r--r--. 1 root root 2007 12月 26 09:19 blk_1073741834_1010.meta
..
# head blk_1073741827
# /etc/services:
..
管理コマンド
# hdfs dfsadmin -report
Configured Capacity: 53660876800 (49.98 GB)
..
Datanodes available: 1 (1 total, 0 dead)
Live datanodes:
Name: 127.0.0.1:50010 (localhost.localdomain)
Zookeeper
# pwd
/etc/zookeeper
# cp zoo_sample.cfg zoo.cfg
https://zookeeper.apache.org/doc/r3.3.3/zookeeperStarted.html#sc_InstallingSingleMode
# zkServer.sh start
Using config: /etc/zookeeper/zoo.cfg
Starting zookeeper ... STARTED
# zkCli.sh
Connecting to localhost:2181
Welcome to ZooKeeper!
[zk: localhost:2181(CONNECTED) 2] ls /
[zookeeper]
[zk: localhost:2181(CONNECTED) 4] create /zk_test my_data
Created /zk_test
[zk: localhost:2181(CONNECTED) 5] ls /
[zookeeper, zk_test]
[zk: localhost:2181(CONNECTED) 6] get /zk_test
my_data
cZxid = 0x2
..
Hbase
参考
http://hbase.apache.org/book.html#quickstart
http://qiita.com/nownabe/items/11ca4744e3c85ed79bea
本家の tarball を使う。
[kanda@localhost opt]$ tar xf /home/kanda/Downloads/hbase-1.2.4-bin.tar.gz
[kanda@localhost conf]$ pwd
/opt/hbase-1.2.4/conf
[kanda@localhost conf]$ cat regionservers
localhost
デフォルトで、 /tmp にデータが置かれるので、他のディレクトリにする。
[kanda@localhost conf]$ vi hbase-site.xml
<configuration>
<property>
<name>hbase.rootdir</name>
<value>file:///opt/hbase</value>
</property>
<property>
<name>hbase.zookeeper.property.dataDir</name>
<value>/opt/zookeeper</value>
</property>
</configuration>
[kanda@localhost hbase-1.2.4]$ export JAVA_HOME=/usr/lib/jvm/java-1.8.0
[kanda@localhost hbase-1.2.4]$ bin/start-hbase.sh
starting master, logging to /opt/hbase-1.2.4/bin/../logs/hbase-kanda-master-localhost.localdomain.out
16010 ポートで、ブラウザアクセスできる。
[kanda@localhost hbase]$ pwd
/opt/hbase
[kanda@localhost hbase]$ ls
MasterProcWALs WALs data hbase.id hbase.version oldWALs
[kanda@localhost hbase-1.2.4]$ bin/hbase shell
HBase Shell; enter 'help<RETURN>' for list of supported commands.
Type "exit<RETURN>" to leave the HBase Shell
Version 1.2.4, r67592f3d062743907f8c5ae00dbbe1ae4f69e5af, Tue Oct 25 18:10:20 CDT 2016
hbase(main):001:0>
hbase(main):002:0> create 'test', 'cf'
0 row(s) in 4.0060 seconds
=> Hbase::Table - test
hbase(main):004:0> put 'test', 'row1', 'cf:a', 'value1'
0 row(s) in 1.5480 seconds
..
hbase(main):008:0> get 'test', 'row1'
COLUMN CELL
cf:a timestamp=1482985443444, value=value1
1 row(s) in 0.2740 seconds
これは、HDFS と動いているのではなかった。
http://hbase.apache.org/book.html#quickstart の 2.3. Pseudo-Distributed Local Install に従う。
<property>
<name>hbase.cluster.distributed</name>
<value>true</value>
</property>
<property>
<name>hbase.rootdir</name>
<value>hdfs://localhost:8020/hbase</value>
</property>
# hdfs dfs -ls /hbase
Found 7 items
drwxr-xr-x - root supergroup 0 2016-12-31 09:38 /hbase/.tmp
drwxr-xr-x - root supergroup 0 2016-12-31 09:38 /hbase/MasterProcWALs
drwxr-xr-x - root supergroup 0 2016-12-31 09:37 /hbase/WALs
drwxr-xr-x - root supergroup 0 2016-12-31 09:35 /hbase/data
-rw-r--r-- 1 root supergroup 42 2016-12-31 09:35 /hbase/hbase.id
-rw-r--r-- 1 root supergroup 7 2016-12-31 09:35 /hbase/hbase.version
drwxr-xr-x - root supergroup 0 2016-12-31 09:35 /hbase/oldWALs
Cassandra
参考。
http://docs.datastax.com/ja/cassandra-jajp/2.0/ 日本語文書がそろっていてありがたいです。
https://wiki.apache.org/cassandra/GettingStarted_JP
datastax (ってなにもの?)にユーザ登録して、そこのリポジトリから入れる。今思うと、本家の tarball を使っても良かったかも。
# dnf install datastax-ddc
インストール:
datastax-ddc noarch 3.9.0-1 datastax-ddc 28 M
datastax-ddc-tools noarch 3.9.0-1 datastax-ddc 5.3 k
中身は。
# rpm -ql datastax-ddc
/etc/cassandra/default.conf/cassandra.yaml
..
/etc/rc.d/init.d/cassandra
/usr/bin/cqlsh
/usr/bin/cqlsh.py
/usr/bin/nodetool
/usr/bin/sstableloader
/usr/bin/sstablescrub
/usr/bin/sstableupgrade
/usr/bin/sstableutil
/usr/bin/sstableverify
/usr/bin/stop-server
..
/usr/share/cassandra/apache-cassandra-3.9.0.jar
..
/var/lib/cassandra/data
/var/log/cassandra
# rpm -ql datastax-ddc-tools
/usr/bin/sstableexpiredblockers
/usr/bin/sstablelevelreset
/usr/bin/sstablemetadata
/usr/bin/sstableofflinerelevel
/usr/bin/sstablerepairedset
/usr/bin/sstablesplit
定義ファイルはここ。
# pwd
/etc/cassandra
# ls conf
README.txt commitlog_archiving.properties
cassandra-env.sh cqlshrc.sample
cassandra-env.sh.orig hotspot_compiler
cassandra-jaas.config jvm.options
cassandra-rackdc.properties logback-tools.xml
cassandra-topology.properties logback.xml
cassandra.yaml metrics-reporter-config-sample.yaml
cassandra.yaml.orig triggers
めんどうなので、ルートで動かす。
# cassandra -f -R
..
INFO 05:08:58 Configuration location: file:/etc/cassandra/default.conf/cassandra.yaml
INFO 05:09:29 Cassandra version: 3.9.0
# nodetool status
Datacenter: datacenter1
=======================
Status=Up/Down
|/ State=Normal/Leaving/Joining/Moving
-- Address Load Tokens Owns (effective) Host ID Rack
UN 127.0.0.1 103.54 KiB 256 100.0% 9bc9192f-1513-4fb4af36-5668bc07eb1f rack1
GettingStarted に従って、テーブルを作成する。
$ cqlsh
Connected to Test Cluster at 127.0.0.1:9042.
[cqlsh 5.0.1 | Cassandra 3.9.0 | CQL spec 3.4.2 | Native protocol v4]
Use HELP for help.
cqlsh> CREATE KEYSPACE mykeyspace WITH REPLICATION = { 'class' : 'SimpleStrategy', 'replication_factor' : 1 };
cqlsh> use mykeyspace;
cqlsh:mykeyspace> CREATE TABLE users ( uid int PRIMARY KEY, name text );
cqlsh:mykeyspace> INSERT INTO users (uid, name) VALUES (1745, 'john');
cqlsh:mykeyspace> INSERT INTO users (uid, name) VALUES (1744, 'jsmith');
cqlsh:mykeyspace> SELECT * FROM users;
uid | name
------+--------
1745 | john
1744 | jsmith
(2 rows)
cqlsh:mykeyspace> SELECT * FROM users WHERE uid = 1744;
uid | name
------+--------
1744 | jsmith
(1 rows)
インデックスが無いカラムは検索できない。
cqlsh:mykeyspace> SELECT * FROM users WHERE name = 'john';
InvalidRequest: Error from server: code=2200 [Invalid query] message="Cannot execute this query as it might involve data filtering and thus may have unpredictable performance. If you want to execute this query despite the performance unpredictability, use ALLOW FILTERING"
cqlsh:mykeyspace> SELECT * FROM users WHERE name = 'john' ALLOW FILTERING;
uid | name
------+------
1745 | john
(1 rows)
原典
元論文と、その、日本語訳もしくは、解説記事など。
・The Google File System - SOPS'03
私は、誤解していたのですが、 GFS は、シングルマスターで、クライアントへのライト完了は全ての複製に書き終わってから返るので、内容の一貫性の問題はなく、 paxos の出番もないのです。
・Bigtable:A Distributed Storage System for Structured Data - OSDI'06
私による Bigtable 論文抄訳
Bigtable というのは、GFSの上に、キーバリュー API をつけて、シャーディングしたことが要点なので、これも、paxos の出番はないのです。つまり、コンテンツの複製の一貫性に使われているわけではないということ。
更新は、ログの形で永続化させるだけ、つまり、メインメモリの最新データに対応する、ディスク上の一つのデータ構造は無い。というのは、 append 以外の更新は高価であるというGFSの特性に制限されるゆえの実装なのでしょうか。それとも、スケーラブルな永続記憶域一般にあてはまるベストプラクティスなのでしょうか。
RamCloud も似たことをしていたけど、インメモリーデータベースの基本?SSDになっても同じ?
・Megastore: Providing Scalable, Highly Available Storage for Interactive Services - CIDR ’11
kuenishi さんによる Google Megastore 解説
論文より。
多くのシステムは Paxos を、ロック、マスター選出、あるいはメタデータと構成の複製のためにだけ使いますが、私達は、Megastore が、主となるユーザデータを、ライトのたびに、複数のデータセンタにわたって複製するために Paxos を使う、実際に配備された最大のシステムだと信じます。
引用終わり。
これが求めるものだった。
ライト遅延は、数百ミリ秒ある。作者も、論文中で「ほとんどのアプリケーションはハッピィだよ」と、気にしている。Spanner の論文では、Megastore は遅くて不人気、と言われている。しかし、 Paxos で地理的に離れたデータセンタ間で複製同期をして、コーディネータのしかけを作ってローカルリードを許し、(私、ここはまだよくわかってない。)たいしたものと思う。ライセンスがゆるいので、ほぼ全訳を掲載できる。
私による Megastore 論文訳
データを複製する文脈では、Paxos の理解は以下で良い。と、思うよ。
5つのサーバがいるなら、3つに複製した時点で、クライアントにライト完了を返してもいい。
読む時は、3つを読めば、必ず最新値を拾う。
1つに書いて、5つを必ず読むというバリエーションもできる。
古典的な二相コミットは、5つに書いて、どれでも一つを読むバリエーションと考えることができる。ただし、トランザクションマネージャつまりリーダーが prepare の後、落ちると、残りのサーバは、データにロックをかけたまま動けなくなる。Paxos はリーダーを選びなおして、続行できる。
以下の Ousterhout 先生のビデオ、おすすめです。一時間ほどで、英語もとても聞き取りやすいです。特に、paxos は、今まで論文を読んでもわからなかったのが、すっきりしました。paxos クイズは、解けなかったけど。
raft 博士論文の抄訳 にある、4ページの paxos の説明もおすすめです。ラーナーは考えないでいいし、プロポーザはアクセプタを兼ねるのです。
Paxos lecture (Raft user study)
Raft lecture (Raft user study)
・Spanner: Google's Globally-Distributed Database - OSDI'12
Spanner - Qiita の、kumagi さんによる解説。この方の、一人トランザクション技術 Advent Calendar 2016 すばらしい。
地理分散DBについて - https://www.slideshare.net/kumagi/db-75506786
451 Unavailable For Legal Reasons にある、GoogleのSpannerに関する論文の和訳
・Dynamo: Amazon’s Highly Available Key-value Store - SOPS'07
@ono_matope さんによる Dynamo日本語訳
・Windows · Azure Storage: A Highly Available Cloud Storage Service with Strong Consistency (SOSP2011)を日本マイクロソフト株式会社が翻訳したものがあります。
・The RAMCloud Storage System - TOCS'15
私による RAMCloud 概要
スタンフォードの Ousterhout 先生のプロジェクトも一段落したようです。
・In Search of an Understandable Consensus Algorithm - USENIX ATC ’14
私による Raft 論文抄訳。raft 博士論文の抄訳 には、Raft クイズがあります。
Raft は、RAMCloud プロジェクトで開発されたコンセンサスプロトコル。etcd, CockroachDB 他でも採用されています。サンプルは、etcd/contrib/raftexample を参照。
http://www.slideshare.net/pfi/raft-36155398 このスライド、USENIX 論文でなくて、完全版の情報も含みます。ありがたいです。
前記、etcd についている raft example を理解するには、以下がよいです。
・私による raft/doc.go の抄訳 raft.Node.Ready の説明があります。
・私による raft 博士論文の抄訳 スナップショットの RPC の説明があります。
・Ceph の論文一覧 http://ceph.com/resources/publications/
博士論文は、200ページもあって挫折した。読むなら、RADOS か。
Ceph: A Scalable, High-Performance Distributed File System - OSDI '06
これ、面白くない。ファイルシステムはスケールしない。これは仕様。パラレルNFSの仕様書を見ること。結局は、POSIX 仕様をゆるめるか、キャッシュコヒーレンシーをより大きくあきらめるかしか、分散ファイルシステムの性能を上げる方法はない。ある意味、やり尽くした感がある。どちらもできる、と言っているのはただのマーケティングハイフ。後は、具体的なアプリケーションごとに妥協点を決めるだけ。スパコンのレガシーアプリが、キーバリューストアAPI に移行すればこの努力も終わる。
http://docs.ceph.com/docs/master/architecture/ が、一番まとまっていると思います。私による ceph architecture の訳 あります。
paxos は、マップを同期させるのに使っているだけ。
・What’s Really New with NewSQL? SIGMOD Record, June 2016
2016年時点での、まとめ。データベース屋さんの意見なので、SQL とトランザクションがなくちゃ、やっぱ、ダメだよね。ってことになる。
・CockroachDB は、Spanner のオープンソースクローン。CockroachDB README と、CockroachDB 設計文書を訳しています。
cockroach/pkg/storage/raft.go
import (
"github.com/coreos/etcd/raft"
なんだ。raft 実装は、coreos なのだ。うーん。こういう部品がころがっていて、使うのが当たり前の時代?
ここで、冬休み、終わり。
解説記事など
kuenishi さんによる クラウド時代の分散データベースを支える技術の応用と進歩
前述、What’s Really New with NewSQL? とあわせて読むべし。
中井さんによる グーグルのクラウドを支えるテクノロジー
なんか、NoSQL 分散記憶域のいい教科書、ないですか。
2018年7月追記。Designing Data-intensive Applications, Martin Kleppmann, O'reilly 読んだ。
私の感想
この十年くらいで、データベースとトランザクションって、けっこう、盛り上がって、進化したんだ。知らなかった。
RCU って、MVCC だよね。OS もデータベースも、ロックフリー、CPU キャッシュを意識する、が当たり前なのですね。
分散トランザクションとインメモリーデータベースは、全ての基本技術。
It Don't Mean A Thing (If It Ain't Got That Scale) スケールしなけりゃ意味がない。
メモリとCPUをけちる奴らに未来はない。
うんざりだわ。ソフトウエアはタダだけど、DRAM 増やすには原価がかかるって。
障害注入と形式検証
面白そうなのでやってみたいが、バグが出そうなところで中断しないと、組み合わせが多すぎるので効率が悪い。どこが弱そうかは、経験で会得するより無いそうな。
Jepsen 一度、さわってみなければ。
TLA+
Software Defined Storage とは
定義は人によって違うのでほとんどバズワードなのだが、Google GFS, Spanner みたいにスケールすることが重要と思うなら、SCSI のブロックライトは単位が小さすぎて、しんどい。強い一貫性を提供できてかつスケールするブロックストレージは幻想。ファイルシステムしかり。少なくても posix 互換なら。1000I/Oするトランザクションなら paxos をかましてもペイするの?
以上