参考
以下の資料参照。
メモ
電力データ活用に関連する、割と新しい情報をまとめた。
メッシュWiFiとは、Elecomの Vol.83 メッシュ(Mesh)Wi-Fiって何?メリットと活用方法を紹介 記事の通り。 戸建ての家などでは、広く安定してカバーできるはず、ということで。
日本国内においてどの機器を使うか?については、 メッシュルーターの選び方について整理した がわかりやすい。
個人的にはIPv6対応している点で、「Synology MR2200ac」が候補に上がった。 仕様は MR2200ac を参照されたし。
v6プラス(IPv6/IPv4インターネットサービス) によると、
「v6プラス」は、NTT東西の次世代ネットワーク(NGN)を利用しインターネット接続を提供するISP事業者が、 IPv6及びIPv4の設備を持たずに、インターネット接続をお客さま(エンドユーザ)にご提供いただくためのサービスです。
とのこと。
Synology製Wi-FiルーターMR2200acでv6プラス接続設定 によると、MR2200acでv6plusを利用する方法が記載されている。
auひかりのホームゲートウェイはいらない? 知っておきたい不都合な真実 にも記載の通り、
先ほどから触れてるとおり、auひかりはホームゲートウェイが無ければインターネットに接続することができません。 その理由は、ホームゲートウェイ内に、KDDIの認証を取る機能があるからです。
とのこと。
そこで、自前のルータを利用したい場合は、 DMZ機能を利用して、ルータ機能をHGWと自前ルータの療法で動かす設定をすることもある。
au光で市販のルーターを使うが参考になる。 ブリッジモードにせずDMZの下でルーターモードで利用するには も参考になる。こちらはtp-linkのブログ。
So-net 光 with フレッツ S 東日本 は、フレッツ光の契約と思われる。
So-net 光 プラスの次世代通信 v6プラス は v6プラス を利用したサービスと思われる。 So-net 光 プラスの次世代通信 v6プラスの対象サービス によると、 So-net 光 プラス などが対応している。 その他フレッツ系のサービスが対応しているようだ。
ipv6 test にアクセスると良い。
Zhamak DehghaniによるHow to Move Beyond a Monolithic Data Laketo a Distributed Data Mesh を読んで簡単にまとめた。
この文章では、ドメインが所有し、提供するデータプロダクトの相互利用に基づく「データメッシュ」の考え方を提唱するものである。 固有技術そのものではなく、アーキテクチャ検討の前の「データを基礎としたサービス開発、ソフトウェア開発のためのデータの取り回し方」に関する示唆を与えようとしたもの、という理解。
Lakehouse A New Generation of Open Platforms that Unify Data Warehousing and Advanced Analytics の論文を確認し、 簡単なメモを作成した。
考え方を節異名しつつ、Delta Lake、Delta Engineを使用した際のTPC−DSの実行結果、クエリ実行コストの情報が記載されていた。 また関連研究、参考文献も過去から現在のトレンドの背景を知る上で参考になるものが多い。
Ansible内で使用する変数を平文でファイルに記載し、プレイブック集に入れ込むのに不安を感じるときがある。 そのようなとき、Ansible Vaultを利用すると暗号化された状態で変数を管理できる。 Ansible Vaultで管理された変数をプレイブック内で通常の変数と同様に扱えるため見通しが良くなる。
公式サイトの Encrypting content with Ansible Vault が網羅的でわかりやすいのだが、 具体例が足りない気がしたので以下に一例を示しておく。 ここに挙げた以外の使い方は、公式サイトを参照されたし。
Ansible-Vaultを用いた機密情報の暗号化のTips も参考になった。
secret.yml 内に変数を記述し、暗号化する。
後ほど暗号化されたファイルを変数定義ファイルとして読み込む。
ここでは以下のような内容とする。
secret.yml
1 | hoge: |
ファイルを暗号化する。
1 | ansible-vault create secret.yml |
上記ファイルを作成する際、Vault用パスワードを聞かれるので適切なパスワードを入力すること。 あとでパスワードは利用する。
1 | ansible-vault decrypt secret.yml |
1 | ansible-vault edit secret.yml |
プロンプトで入力する代わりに、どこかプレイブック集の外などにVaultパスワードを保存し利用することもできる。
ここでは、 ~/.vault_password
にパスワードを記載したファイルを準備したものとする。
編集する例を示す。
1 | ansible-vault edit secret.yml --vault-password-file ~/.vault_password |
変数定義ファイルとして渡し、プレイブック内で変数として利用する。 以下のようなプレイブックを作る。
test.yml
1 | - hosts: localhost |
以下、簡単な説明。
secret.yml を指定(
vars_files の箇所)secret.yml
に記載されたとおり、構造化された変数 hoge.fuga
の値を利用する。foo
という内容がSTDOUTに表示されるはず。プレイブックを実行する。
1 | ansible-playbook test.yml --ask-vault-pass |
Hexo 記事に画像を貼り付ける を参考に、もともとCacooのリンクを使っていた箇所を すべてスタティックな画像を利用するようにした。
post_asset_folderを利用して、記事ごとの画像ディレクトリを利用することも考えたが、 画像はひとところに集まっていてほしいので、 Global-Asset-Folder を利用することにした。
なお、上記ブログでは
1 | プロジェクトトップ/images/site |
以下に画像を置き、
1 |  |
のようにリンクを指定していた。
自身の環境では、rootを指定しているので
1 | プロジェクトトップ/image |
以下にディレクトリを置き、
1 |  |
と指定することにした。
Delta Lake High-Performance ACID Table Storage over Cloud Object Stores や Lakehouse A New Generation of Open Platforms that Unify Data Warehousing and Advanced Analytics の論文の通り、 Delta Lakeはキャッシュとの組み合わせが可能である。
今回は、ストレージにHDFS、キャッシュにAlluxioを使って動作確認する。
ansible-bigdata あたりを参考に、Hadoopの疑似分散環境を構築する。 Bigtopベースの2.8.5とした。
併せて、同Ansibleプレイブック集などを用いて、Spark3.1.1のコミュニティ版を配備した。
併せて、Alluxioは2.5.0-2を利用。
Alluxioに関しては、以下のようにコンパイルしてパッケージ化して用いることできる。
1 | sudo -u alluxio mkdir /usr/local/src/alluxio |
コンフィグとしては以下を利用。
1 | $ cat conf/alluxio-site.properties |
ポイントは以下の通り。
/alluxioを利用1 | sudo -u alluxio ./bin/alluxio format |
テストを実行
1 | sudo -u alluxio ./bin/alluxio runTests |
もしエラーが生じた場合は、例えばHDFSの/alluxioディレクトリに、 適切な権限設定、所有者設定がされているかどうかを確認すること。
Alluxioが起動すると以下のようなUIを確認できる(ポート19999)
先程テストで書き込まれたファイル群が見られるはず。
ここでは、上記の通り、環境を整えた前提で以下説明する。
Examples: Use Alluxio as Input and Output を参考に、Alluxio経由での読み書きを試す。
予め、今回の動作確認で使用するテキストデータ(AlluxioのREADME)をアップロードしておく。
1 | $ sudo -u alluxio /opt/alluxio/default//bin/alluxio fs copyFromLocal /opt/alluxio/default/LICENSE /LICENSE |
予め、以下のような設定をspark-defaults.confに入れておく。 Alluxioのクライアントライブラリを用いられるように。
1 | spark.driver.extraClassPath /opt/alluxio/default/client/alluxio-2.5.0-2-client.jar |
Sparkが起動することを確認する。ここではDelta Lakeも含めて起動する。
1 | /usr/local/spark/default/bin/spark-shell \ |
起動したシェルでAlluxio上のREADMEファイルを読み取り、行数を確認する。
1 | scala> val pathOnAlluxio = "alluxio://localhost:19998/LICENSE" |
準備として、Alluxio上に、dobachiユーザ用のディレクトリを作成してみる。
1 | sudo -u alluxio /opt/alluxio/default/bin/alluxio fs mkdir /users |
先程起動しておいたシェルで、Delta Lake形式のデータを書き込んで見る。
1 | scala> val data = spark.range(0, 5) |
すると以下のようなエラーが生じた。
1 | scala> data.write.format("delta").save(outputUrl) |
当たり前だが、Delta Lakeの下回りのストレージとして標準では、 Alluxioが対応しておらず、LogStoreからエラーが生じた、ということのようだ。
一瞬、LogStoreを新たに開発しないといけないか?と思ったものの、よく考えたら、HDFSHadoopFileSystemLogStoreから Alluxioのスキーマを認識させてアクセスできるようにすればよいだけでは?と思った。 そこで、Hadoopの設定でAlluxioFileSystemをalluxioスキーマ(ファイルシステムのスキーマ)に明示的に登録してみる。
/etc/hadoop/conf/core-site.xmlに以下を追記。
1 | <property> |
再びSparkを立ち上げ、適当なデータを書き込み。
1 | scala> val data = spark.range(0, 5) |
以上のように書き込みに成功した。
つづいて、テーブルとして読み出す。
1 | scala> val df = spark.read.format("delta").load(outputUrl) |
テーブルへの追記。
1 | scala> val addData = spark.range(5, 10) |
また、追記書き込みをしたのでDeltaログが増えていることが分かる。 (3回ぶんのログがあるのは、↑には記載していないがミスったため)
Sparkでの処理実行時にYARNで実行していたところ、Executorにおける処理からAlluxioを呼び出すときにエラー。
yarnユーザでのアクセスとなり、HDFS上の /alluxio
へのアクセス権がなかったと考えられる。
1 | 21/01/05 02:54:35 WARN TaskSetManager: Lost task 0.0 in stage 0.0 (TID 0, hadoop-pseudo, executor 2): alluxio.exception.status.UnauthenticatedException: Channel authentication failed with code:UNAUTHENTICATED. Channel: GrpcChannelKey{ClientType=FileSystemMasterClient, ClientHostname=hadoop-pseudo.mshome.net, ServerAddress=GrpcServerAddress{HostName=localhost, SocketAddress=localhost:19998}, ChannelId=81f7d97f-8e32-4289-bcab-ea6008d5ffac}, AuthType: SIMPLE, Error: alluxio.exception.status.UnauthenticatedException: Plain authentication failed: Failed to authenticate client user="yarn" connecting to Alluxio server and impersonating as impersonationUser="vagrant" to access Alluxio file system. User "yarn" is not configured to allow any impersonation. Please read the guide to configure impersonation at https://docs.alluxio.io/os/user/2.4/en/operation/Security.html |
Alluxio Security のドキュメント中に「Client-Side Hadoop Impersonation」を読むと、 「なりすまし」を許可する設定があるようだ。
そこで、yarnユーザが様々なユーザになりすませるような簡易設定を以下のように加えることにした。
実際の運用する際は、なりすましのスコープに注意したほうが良さそうだ。
conf/alluxio-site.properties
1 | alluxio.master.security.impersonation.yarn.users=* |
ドキュメントではクライアントで
alluxio.security.login.impersonation.username
も指定するよう書かれていたが、
起動時にしてしなくてもアクセスできるようになった。
あとで実装を調べたほうが良さそうだ。
オープンになっている情報を中心に既存情報を軽くまとめる。 特にデータ処理、データ活用との関連を探る。
ガートナー、「先進テクノロジのハイプ・サイクル:2020年」を発表 の記事によると、 2020/8/19にハイプ・サイクルが発表された。
記事冒頭で触れられているとおり、COVID-19の影響は否定できない。 例ではヘルス・パスポート、ソーシャル・ディスタンシング・テクノロジが挙げられていた。 記載されているととおり、「過度な期待」として初登場する技術は少ないのだが、 それに該当するということで注目されている。
週刊ダイヤモンド 2020年12/12号 の中に、 「NTT帝国の逆襲」という特集記事がある。
技術というより、事業職が強いが念の為に(あえて)技術に関連するキーワードだけ述べる。 なお、この書籍で重要なのは、本来はどちらかというとビジネス戦略側面である。 詳細は当該書籍を参照されたし。
技術キーワード
あくまで公開された情報ではあるがリスト化しておく。
2020/12時点で、Kafka Connectのプラグインの参考になるもの探す。
kafka-connect-syslog が最も簡易に動作確認できそうだった。 ただ、 ConfluentのGitHub を見る限り、GitHub上には実装が公開されていないようだった。
ここでは、ローカルに簡易実験用の1プロセスのKafkaを起動した前提とする。 起動方法は Kafkaのクイックスタート を参照。
kafka-connect-syslog
のパッケージをダウンロードして /opt/connectors
以下に展開。
1 | $ cd /opt/connectors |
というパッケージが展開される。
動作確認に使用するプロパティは以下。
1 | $ cat etc/minimal-tcp.properties |
また、Connectの設定には以下を追加する。
/opt/kafka_pseudo/default/config/connect-standalone.properties
1 | (snip) |
プラグインを置く場所として、 /opt/connectors
を指定した。
/opt/kafka_pseudo/default/bin/connect-standalone.sh
を利用して、 スタンドアローンモードでKafka Connectを起動。
1 | sudo -u kafka /opt/kafka_pseudo/default/bin/connect-standalone.sh /opt/kafka_pseudo/default/config/connect-standalone.properties \ |
起動したのを確認し、別の端末から適当なデータを送信。
1 | echo "<34>1 2003-10-11T22:14:15.003Z mymachine.example.com su - ID47 - Your refrigerator is running" | nc -v -w 1 localhost 5515 |
Console Consumerを利用して書き込み状況を確認。
1 | cd ${KAFKA_HOME} |
先程書き込んだものが表示されるはずである。
kafka-connect-datagen もあった。 kafka-connect-datagenのGitHub に実装も公開されているように見える。 ドキュメントのリンクから、当該レポジトリのREADMEにジャンプしたため、そのように判断。
以降、v0.4.0を対象として確認したものである。
指定されたスキーマで、ダミーデータを生成するコネクタ。 avro-random-generator を内部的に利用している。
スキーマ指定はAvroのスキーマファイルを渡す方法もあるし、 組み込みのスキーマを指定する方法もある。 kafka-connect-datagenのサンプルスキーマ を参照。
また、Kafkaに出力する際のフォーマットは指定可能。 Kafka
Connect自体の一般的なパラメータである、 value.converter
を指定すれば良い。 例えば以下の通り。
1 | "value.converter": "org.apache.kafka.connect.json.JsonConverter", |
2020/12/21時点では本プロジェクトのバージョンは0.4.0であり、
1 | <parent> |
の通り、Confluent Platformのバージョンとしては、6系である。
Confluent Platform and Apache Kafka Compatibility によると、 Confluent Platform 6系のKafkaバージョンは2.6.Xである。
io.confluent.kafka.connect.datagen.DatagenConnector
クラスは、 org.apache.kafka.connect.source.SourceConnector
を継承している。 割と素直な実装。
io.confluent.kafka.connect.datagen.DatagenConnector#start
メソッドは特別なことはしておらず、 コンフィグをロードするだけ。
io.confluent.kafka.connect.datagen.DatagenConnector#taskConfigs
メソッドも 特別なことはしていない。start時に受け取ったプロパティから
taskConfigを生成して返す。
io.confluent.kafka.connect.datagen.DatagenConnector#stop
メソッド および、
io.confluent.kafka.connect.datagen.DatagenConnector#config
もほぼ何もしない。
タスクには
io.confluent.kafka.connect.datagen.DatagenTask
クラスを利用する。
io.confluent.kafka.connect.datagen.DatagenTask#start
メソッドが overrideされている。 以下、ポイントを確認する。
オフセット管理の仕組みあり。
io/confluent/kafka/connect/datagen/DatagenTask.java:133
1 | Map<String, Object> offset = context.offsetStorageReader().offset(sourcePartition); |
io.confluent.avro.random.generator.Generator
のジェネレータ(のビルダ)を利用する。
io/confluent/kafka/connect/datagen/DatagenTask.java:141
1 | Generator.Builder generatorBuilder = new Generator.Builder() |
クイックスタートの設定があれば、それに従ってスキーマを読み込む。
io/confluent/kafka/connect/datagen/DatagenTask.java:144
1 | String quickstartName = config.getQuickstart(); |
指定されたクイックスタート名に従い、パッケージに含まれるスキーマファイルを読み込み、 それを適用しながらジェネレータを生成する。
なお、クイックスタートのたぐいはenumで定義されている。
io/confluent/kafka/connect/datagen/DatagenTask.java:75
1 | protected enum Quickstart { |
クイックスタートが設定されておらず、スキーマの文字列が与えられた場合は、 それを用いてジェネレータが生成される。
io/confluent/kafka/connect/datagen/DatagenTask.java:164
1 | } else if (schemaString != "") { |
それ以外の場合、つまりスキーマ定義の書かれたファイルを指定する場合は、 以下の通り。
io/confluent/kafka/connect/datagen/DatagenTask.java:166
1 | { |
最後のAvroに関連する情報を生成して終了。
io/confluent/kafka/connect/datagen/DatagenTask.java:184
1 | avroSchema = generator.schema(); |
io.confluent.kafka.connect.datagen.DatagenTask#poll
メソッドもoverrideされている。 以下、ポイントを記載する。
インターバル機能あり。
io/confluent/kafka/connect/datagen/DatagenTask.java:192
1 | if (maxInterval > 0) { |
ジェネレータを利用し、オブジェクトを生成する。
io/confluent/kafka/connect/datagen/DatagenTask.java:201
1 | final Object generatedObject = generator.generate(); |
生成されたオブジェクトから、スキーマ定義に基づいてフィールドの値を取り出し、 バリューのArrayListを生成する。
io/confluent/kafka/connect/datagen/DatagenTask.java:210
1 | final List<Object> genericRowValues = new ArrayList<>(); |
キーも同様に取り出し、Kafka Connectの形式に変換する。
io/confluent/kafka/connect/datagen/DatagenTask.java:224
1 | SchemaAndValue key = new SchemaAndValue(DEFAULT_KEY_SCHEMA, null); |
先程ArrayListとして取り出したバリューもKafka Connect形式に変換する。
io/confluent/kafka/connect/datagen/DatagenTask.java:233
1 | final org.apache.kafka.connect.data.Schema messageSchema = avroData.toConnectSchema(avroSchema); |
イテレートのたびに、メタデータを更新する。
io/confluent/kafka/connect/datagen/DatagenTask.java:246
1 | // The source offsets will be the values that the next task lifetime will restore from |
最後に、SourceRecordのリスト形式に変換し、 レコードとして生成して戻り値として返す。
io/confluent/kafka/connect/datagen/DatagenTask.java:261
1 | final List<SourceRecord> records = new ArrayList<>(); |
つづいて、
io.confluent.kafka.connect.datagen.DatagenTask#stop
メソッドだが、 これは特に何もしない。
io.confluent.kafka.connect.datagen.DatagenTask#getOptionalSchema
という
オプショナルなフィールドに関するスキーマを取得するためのヘルパーメソッドもある。
io.confluent.kafka.connect.datagen.DatagenTask#getOptionalValue
メソッドもある。
confluentinc-kafka-connect-datagen-0.4.0.zip をダウンロードし、
/opt/connectors以下に展開したものとする。
今回は以下の設定ファイルを参考に、データ生成してみる。 なお、イテレーション回数は適度に修正して用いることを推奨する。
confluentinc-kafka-connect-datagen-0.4.0/etc/connector_users.config
1 | { |
上記はconfluentコマンド用で利用する際のコンフィグファイルである。 そこで以下のようなKafka Connect用の設定ファイルを生成する。
/opt/connectors/confluentinc-kafka-connect-datagen-0.4.0/etc/connector_users.properties
1 | name=users |
スタンドアローンモードでKafka Connectを起動する。
1 | sudo -u kafka /opt/kafka_pseudo/default/bin/connect-standalone.sh \ |
停止した後、結果を確認する。 トピックが作られたことがわかる。
1 | /opt/kafka_pseudo/default/bin/kafka-topics.sh --bootstrap-server localhost:9092 --list |
データを確認する。
1 | /opt/kafka_pseudo/default/bin/kafka-console-consumer.sh --bootstrap-server localhost:9092 --topic users --from-beginning |
ダミーデータが生成されていることが確認できた。
(WIP)
プロジェクト内に、sbt自体を含めてクローンしただけでビルドできるようにしたい、という動機。 現時点ではCoursierプロジェクトが汎用性※が高く便利であると、個人的には感じた。
※ここでは、多くの環境で実行可能で、様々なツールを一度にセットアップ可能という意味。
Coursier を使って最速でScalaの開発環境を整える のブログに記載されているとおり、 Scala開発環境を簡単に整えられる。
ひとまずDocker内で試す。
1 | sudo docker pull ubuntu:18.04 |
Dockerコンテナ内でインストール。
1 | apt update |
結果として以下がインストールされた様子。
1 | Checking if the standard Scala applications are installed |
~/.profileに環境変数等がまとまっているので有効化する。
1 | # source ~/.profile |
これでインストールされたコマンドが使用できるようになった。
なお、参考までに上記でダウンロードしたcsコマンドは以下の通り。
1 | $ ./cs setup --help |
sbt-launcher-package をビルドすることでSBTランチャーを提供できそうだった。
https://github.com/sbt/launcher/blob/1.x/.java-version にも記載されているとおり、 JDK7系にしか公式に対応していなかった。