【シェル】ヒアドキュメントのEOFの前にスペースは入れてはいけない

みたいです。

これはちょっとハマりました。

ヒアドキュメントとは

ヒアドキュメントという機能を知っていますでしょうか?

簡単に言えば複数行で文字列を表示させる機能です。


Qiitaで探すといっぱいでてきます。
詳しい機能は下記など、いろいろ探してみてください。
qiita.com


ざっくり使い方

コマンドは下記のように使えます。

$ cat << EOF
> aaa
> bbb
> ccc
> EOF
aaa
bbb
ccc

シェルスクリプト

もちろん同じようにシェルスクリプトで使うこともできます。

eof_test.sh

cat << EOF
aaa
  bbb
ccc
  ddd
EOF

でなにが問題か?

functionで使ってみる

function内で使おうとすると、下記のようにインデントを入れて使いたくなります。

eof_test.sh

function hoge() {
  cat << EOF
  hoge
  EOF
}
hoge

でこれを実行するとエラーになります。

eof_test.sh: 行 7: 警告: ヒアドキュメントの 3 行目でファイル終了 (EOF) に達しました (`EOF' が必要)
eof_test.sh: 行 8: 構文エラー: 予期しないファイル終了 (EOF) です

なのでEOFがある行の行頭スペースを除けばOKです。

function hoge() {
  cat << EOF
#cat << EOF ←この行も行頭スペースなしにしてもいい
  hoge
EOF  # ←この行頭スペースを省く
}
hoge

これがzshで実行すると…?

でここが核心なのですが、たまたまこのようなスクリプトzshで実行してたんですね。
zshで実行するとエラーログがこんなのでます。

eof_test.zsh:7: parse error near `\n'

なんのエラーなのかわからない!!!(ToT;;)


shで実行した場合はこんな風にでます。

eof_test.sh: 行 7: 警告: ヒアドキュメントの 3 行目でファイル終了 (EOF) に達しました (`EOF' が必要)
eof_test.sh: 行 8: 構文エラー: 予期しないファイル終了 (EOF) です

なので、あーEOF付近のエラーだなと推測がつくのですが
zshは全然どこが悪いのか推測がつかなかったので
かなり時間を浪費しました。


しかもエラーが出た時は数百行のスクリプトのかなり上の方にEOFを書いてて
エラー指摘の行が一番最後だったので、エラー原因を探るのにかなり苦労しました…。



このことが誰かの役に立ちますように。。。



入門UNIXシェルプログラミング―シェルの基礎から学ぶUNIXの世界

入門UNIXシェルプログラミング―シェルの基礎から学ぶUNIXの世界

新しいシェルプログラミングの教科書

新しいシェルプログラミングの教科書

Hiveでpartitionはテーブル定義と紐づいているようだ

Hiveのテーブルにカラムを追加した時に
追加したカラムがスッカスカでデータが取れないことがあった。

結論から言うと、パーティションが変更前のテーブル定義と紐づいてるから
追加カラムの値が取れなかったってこと。

なのでパーティションを作り直すと追加カラムのデータが取れた。


そのことを知見として書き留めておこう。

データ

こんなデータ

hoge_data.tsv.gz (↓タブ区切りね)

id	name
001	hoge
002	fuga
003	mohimohi

最初のテーブル定義

パーティションは適当、でもこれがくせもの。
external じゃなくてもいいかも、たぶん。

name カラムが無いことに注意。あとから作る。

create external table if not exists hogehoge_table (
  id     string
)
partitioned by (
  version string
)
row format delimited fields terminated by '\t' null defined as '' stored as textfile
location '/hoge/test.db/hogehoge_table';

フォルダ作成

hdfsに下記のフォルダを作っておき、hoge_data.tsv.gzを入れておく。
/hoge/test.db/hogehoge_table/version=1234

パーティション作成

Hiveを起動して下記コマンド。自分はbeeline使ってるけど、普通は何使うんだろう?

alter table hogehoge_table add partition (version="1234");

SQL

でさっそくSQLを実行してみる。

select * from hogehoge_table where version="1234";

hogehoge_table.id    hogehoge_table.version
001                           1234
002                           1234
003                           1234

予想通りに取れる。

カラムを追加する

alter table hogehoge_table add columns (
  name     string
);
select * from hogehoge_table where version="1234";
hogehoge_table.id      hogehoge_table.name         hogehoge_table.version
001                                                    1234
002                                                    1234
003                                                    1234

→name 列が取れてない!

パーティションを削除してもう一回作る

alter table hogehoge_table drop partition (version="1234");

alter table hogehoge_table add partition (version="1234");

もう一回SQL実行

select * from hogehoge_table where version="1234";

hogehoge_table.id   hogehoge_table.name   hogehoge_table.version
001                         hoge                    1234
002                         fuga                    1234
003                       mohimohi                  1234

→name列が取れてる

結論


でもな、impalaではこんなことは起きなかった。
なんでだろうね。

参考

別の人も同じこと起きてるみたい。

bigpicture.pl


Hiveのwiki見るとSQLの書き方が書いてある。
LanguageManual DDL - Apache Hive - Apache Software Foundation

ALTER TABLEの時にPARTITION入れればいいのね。

ALTER TABLE table_name [PARTITION partition_spec] ADD COLUMNS (col_name data_type ...);

プログラミング Hive

プログラミング Hive

  • 作者: Edward Capriolo,Dean Wampler,Jason Rutherglen,佐藤直生,嶋内翔,Sky株式会社玉川竜司
  • 出版社/メーカー: オライリージャパン
  • 発売日: 2013/06/15
  • メディア: 大型本
  • この商品を含むブログ (3件) を見る
ビッグデータ分析・活用のためのSQLレシピ

ビッグデータ分析・活用のためのSQLレシピ

数学検定を受けてきました。

f:id:suganoo:20180417130602j:plain
準1級です。
高校レベルの数学です。

なんでー高校レベルかよっと思ってましたが、
卒業してから20年近くたってるので、解放はほぼ忘れてました。

数列、ベクトル、行列、極限、楕円曲線/双曲線、微分積分・・・・

去年の秋から取り組んでましたが、やってみると
計算のやりかたなんかけっこう覚えてるものですね。

数学好きでよかった。

なんで数学検定?

高校生まで数学は好きで得意だったのですが、
学生時代はバイオ系の学部だったのであまり数学をやらず、
それがすごーく心残りだったんです。

うーっ.....偏微分とか高度な数学やってみたい!

っとこの20年考えてました。


また、機械学習やデータ分析、人工知能とどんどん新しい技術が出てきてます。

その根幹は数学や統計学です。

そういった分野の仕事もしてみたいなー
でも経験がない。どうしよ?っと考えて

おそらくnumpy,pandas,scikit-learnやRやDeep learning
ツールでしかないから覚えてもいつかは新しいツールがまた出るだろう。
(当然できたほうが有利だけどね)
また子供が小さいから、勉強の時間もとれない。

だったら、先に数学をしっかりやっておこうと思ったのです。

なので早く1級の分野がやりたい!

試験はどうだったか

4/15が受験日だったのですが、1次試験はなんとかなったものの
2次試験が半分くらいしかできなかった。。。


はやく答え合わせしてみたい。

たぶん結果はダメだと思うので、次回7月の試験を目指します。

それにしても試験時間中、数学解いてるのが楽しかったなあ。

使った参考書など

U-CANの数学検定準1級ステップアップ問題集 (ユーキャンの資格試験シリーズ)

U-CANの数学検定準1級ステップアップ問題集 (ユーキャンの資格試験シリーズ)

1冊を何度もやるのは飽きてしまい、2冊読み通しました。
どっちか1冊でいいでしょう。

ためせ実力!  数学検定準1級実践演習

ためせ実力! 数学検定準1級実践演習

この最後の3冊目の参考書はなかなかレベルが高くて
問題解いてて楽しかったですよ。


うん 数学力を今後の業務のアピールにしたいなあ。
さーまた頑張ろう

30代以上で子供がいて家事もしてるエンジニアは今後どうやって勉強するべきか

f:id:suganoo:20180403125030j:plain
自分は去年2017/6月に娘が生まれた。
そして今年2018で37歳になる。

けっこう家事はやってる方だと思うんだけど
プライベートの時間がかなり減った。

男という生き物はどうしても家事を嫁さんにやらせがちと聞くので
結婚した時に家事はなるべく率先して家事をしようと思った。
別に嫌いでもないし、食べることや料理が好きだったし
家のことを自分でコントロールしているというのはなかなか楽しいものだ。

夫婦共同生活が始まり、家事をなるべくやるようになったが
プライベートの時間やお勉強時間がかなり減った。

そして子供が産まれてさらに時間が減った気がする。
産まれた直後は寝る時間も減ったが、今はなんとか夜は寝てくれている。


自分はITエンジニアとしてやってきたい。
だからこそお勉強はしたい。

じゃあ休みの日に本を読んだり、プログラミングの勉強をして
家事や育児のことををほうっておいて
ひとりでMacBookを開いてるのもすごく気が引ける。


結婚して、子供が産まれて自分の時間が減ったことは
嫌ではないし、しかたのないことだし、
むしろ独身だったころにはない楽しい充実した時間が増えてはいる。

だけどもだからといってお勉強のインプットが減ってしまうのは悩ましく
知識欲が満たされないというのもフラストレーションだし
今後の仕事も心配になるし、モチベーションがあがらなくなるのがもっと心配だ。


ここ数年で様々な新しい技術が出てきた。
データ分析、機械学習、AI、仮想化技術、仮想通貨......
新しい分野が出てきては優秀な若手がtechyなアピールをして
それを見るたびにすごい若手だ、と思うと同時に
うらやましく、そしてうすら寒い焦りの気持ちが湧いてくる。


20代のころはわからないことだらけで
時間は無いといいつつも振り返ると今以上に時間は取れていたので
週末はプログラミングコンテストやってみたり、資格の勉強したり、
StartUpWeekEndに参加したり、中古PCでLinuxサーバー構築してみたり、
ネットワーク/アルゴリズムを勉強してみたり、などなど興味のある限り
手をだして勉強して、勉強会にも行ってた気がする。


だけども、今はもうそんなことはできない。

そう思うと焦燥の念が出てくるがこれはもう落胆するのではなく、
自分のやり方を進化させるべき時なのだと考えることにした。


そこでいろいろ考えてみたこと試してることを書いてみる。
誰かの役に立てば幸い。


強くなる分野を決める

なにがしたいのか?どんな分野に強くなりたいのか?
をすごく自問自答する。なるべく狭くね。
そんでその分野を勉強して磨きをかける。

興味をもった分野なんて絶対誰か第一人者がいる。
興味ある分野を調べると必ずすごい人がいて
あぁ自分は大したことないのだなと自己嫌悪するけど
得意な武器があれば、年齢とともに増えるがっかり感を減らすことができる(気がする)。

得意な武器を持っているほうが
環境が変わっても、どんな分野にいっても
通用するはず(だとも思ってる)。


インフラエンジニアとして強くなりたい。
いまのところ。

今のところ、Go言語、インフラ知識、数学かな。
あと趣味として語学。

なんかこれだけでもちょっと多いような気も。
まあいいや。
でもとりあえず、この3つの分野なら興味もあるし
深めていきたいと思っている。


やらないことを決める。

中途半端な知識とかしかなければ若手にまかせていいし
自分が強くなれそうもない分野に時間をかけても
そんなにメリットが多くない気がする。
やっぱり得意分野に注力したほうがいいでしょう。


自分ならRubyjavaはやらないと決めた。

この2つはプログラミングスクールとかいっぱいあるし
年齢、仕事の経験から今からやっても勝てそうにない。

Ruby は書けるが、やる機会がほんとに少なくなったので
すっぱりやめる。
Ruby on Rails とかできたら、需要高そうだし
いろんな会社で働けそうだし、自分でwebサービスとか
作れそうだなと思ったけど、うん、やめる。

転職するときに副業とかできないかなと思って
rails に手を出したことがあったけど
ぜんぜん伸びなかったしね。

javaはできる人を見てると玄人すぎて
勝てる感じがしないし、mavanとかEclipseとか
javaに付随する技術が多くて独学習得するには俺は無理。。。
javaでできたプロダクトは多くて心苦しいけど
うん、やめる。


あでも、仕事で使う必要になったら別だけど。

やたら手を広げないで、深めることを目標としたい。


あと夕方19時以降の勉強会は出ない
出られないのが現実だけども
単位時間あたりの効果は薄い。

その技術は何が問題として存在し何を解決するのか

新しい技術が出てきたとき、まあかじって
勉強してみようと手を出すことがある。

ほーん、まあこれxxxの業務で使えそうだなと思って
やってみたら、メンテナンスが煩雑になってしまい
枯れたこれまでのものを使っとけばよかったというのがよくある。

それで知見がたまるというのはいいのだけども
やっぱりなんの目的でそれを使うのかが
わからないと有効活用ができないでしょう。


CIツールみたいなpythonライブラリを前任者が使っていたことがあった。
データ加工をスクリプト上で書いて、それを定期実行できるというもの。
データ加工クラスをスクリプト上で同時並列とか定義できたり、
データ加工タスクの関係性をブラウザ上で見ることができる
とかの機能メリットがあったのだけど、
実際やってることが、1,2ステップしかなくて
結局jenkinsでよかったじゃんってことがあった。


他にもデータ処理を流行りのScala+Spark使って処理できそうじゃんと
やってみたら、時間間隔が長くてAmazon S3 + SQSでよくねえ?とか


何のためにそれを取り入れるのか?が大事。


例えばDockerはそれまで何が課題で、どんなメリットがあるのか?とか
考えて使えるのがいいよね。

原理的なところを重点的にやる

機械学習人工知能の仕事をやってみたい。

ただ自分の経験だとHadoop使ったことあるとか
python, Goが使えるだけで
コアな部分は未経験だからアピール材料が乏しく行けそうにもない。

じゃあTensorflowとかAnaconda, jypiterを勉強しようかと
思っても時間もお金もない。

たぶんだけど、ああいうツールは現場で働いたり
したらそんな習得は大変ではなく
もっと大事なのは数学的なところじゃないのかと思ってる。


だからこそ数学(数学検定)をもくもくと通勤電車で読んでいる。

あまり時間が確保できない状況だからこそ
その技術のコアな部分を勉強するのがいいのではないか。

例えば、ビッグデータのカラム指向について
カラム指向のDBは中身がどうなってるのか?とか
GoogleのDremelの論文を読んでみるとか
時間がないなりに原理的なコア技術を読んでおくのが
あとあと効いてくると思っている。

なるべく本で勉強する。

昔の人間なので紙の本が好き。
ぱっとみどこまで読んだかわかるし
読了後に達成感がある。

電子書籍だと読みながらどこまでこの内容がつづくのだと
疲れてくるし、本ではないから読むこと自体すぐに忘れて
kindle内積読が増えるのが難点。

お勉強には紙の本の方が効率的な気がする。

読もうとする本を吟味してから読み始める

やたらめったら興味のある本に手を出してたこともあるけど
やらないことを決めるように、吟味して本を選ぶ。
時間は有限だからね。

Code Completeの下巻をがんばって読もうかと思ったけど
時間と得られる知識を考えて、下巻はやめた。

あと読む前に本の「はじめに」と構成目次をよく読んでおくのはおすすめ。
読む前から、著者のほんんんとーーに言いたいことは何なのか?
を頭をこれまでの3倍くらい振り絞って想像してから読み始めると
吸収が全然違う。

この作業はおすすめ。


online コースを利用して勉強する

勉強方法を工夫する。
Udemyをやってみたが、電車の中でも動画が見れて
学べるのでなかなかよかった。

他にN予備校とかprogateをやってるけど
会社の昼休みでもちょこちょこできるから
すきま時間に学ぶことができるからいい。

もうちょっと時間が確保できるようになったら
couseraとかもやってみたいところ。


onlineコースの勉強はおすすめ。

資格取得を利用する

漏れや偏りなくその分野を知るためにはとても効率がいい。

人工知能機械学習のために数学をやり直したく
数学検定を目標としているが
あの膨大な数学をコンパクトにレベル分けしてくれて
分野別に広く網羅的に学べるのはすごく効率がいい。


過去にネットワークスペシャリスト資格も勉強していたが
すごく網羅的にネットワークの知識が吸収できてとてもよかった。
(結局6回くらい落ちてあきらめた)


ただ30すぎて実用的でない資格にこだわるのはよくないとも思えるので
資格の効果をよく考えよう。


休日の朝から勉強する

お勉強の時間を確保するために、仕事から帰ってから
睡眠時間を削ってお勉強するのは、やっぱりあんまり得策ではない。

30すぎるとほんと体力なくなってきて睡眠時間が大事になる。

なので夜は23:30過ぎたら本を開くことなく
さっさと寝ることにしてる。

で時間を確保するために、休日の朝の1時間でも30分を
読書にあてて勉強するとかなり効率がいいことに気付いた。

金曜の夜であっても24時前に寝るようにすれば
けっこう休日でも起きられる。

睡眠時間がしっかりとれていると
やっぱり語学の物覚えもよくなってることに気付く。

プラスアルファとしてそのまま洗濯機をかけて
朝食をしっかり作っておくと奥さんからほめらるかもしれない。
「当たり前じゃない」ってね。

長い通勤時間を逆手に取る

片道1時間かかってるけど、ほんとこの往復2時間は貴重な読書時間。

よく職住接近とかいうけど自分は意志が弱いし
家族がいる中で家で勉強時間を確保するのはすごく難しいのではと思う。

まあ人それぞれなんだけど
通勤時間は有効活用したいよね。

あと通勤時間のスマホを使用厳禁にする。
これだけでかなり集中できる。

完全には無理でも週3日でもいい。
貴重な自分の時間はなるべく確保したい。



それにしても家の近くにサテライトオフィスができたりしたらいいなあ。

仕事の方向性を変える

エンジニアとして働いてると技術知識を偏重してしまい
できる人と言えば、すごい技術を持った人と考えてしまう。

それもそうなんだけど、技術は業務が良くなってくれないと意味がない。

なので今やってる業務知識をつける、どう使いやすくなってほしいか?
をもっと突き詰めて考えたほうがいいだろう。

社内で情報共有のためのWebサイトを作るために、rails がいいのかPHPがいいのかなんて
どうでもいいし、メールでもいいのかもしれない。
なんなら手書きの掲示板でもいいかもしれない。

要するに何を解決するのか?を考えていくと
もっとできるエンジニアになれる(はず)。

そうすれば知識ではない部分が鍛えられるし。



雑多に所感を書いてみたけど、どこか矛盾があるかもしれないし
明日には気が変わるかもしれない。

他にお勉強hackはどんなのあるだろうかね。

技術者派遣でまともな仕事に就くにはどうすればいいのか

しばらく前のことだけど
増田のこんな記事がバズってた。

ちょっと長いのでざっくりしか読んでないけど。
anond.hatelabo.jp

自分もこれまでずーっと技術者派遣で働いている。

転職を2回ほどして、なかなか技術的な仕事してるので
この記事だといわゆる技術者派遣の強者側に立っているのかもしれない。
今の仕事内容は充実してるし、そんなに不満もない。

どうやってこちら(強者)側になれたかと言われても
自分でもよくわからない。

「強者」というのもおこがましいけど
雑用的な仕事しかしてない人から見たらそうなのかも。



思い起こすと自分が20代だったころを思い出すと
この記事ほどではないが、あんまりいい仕事した思い出は無い。

お台場のビルの一室でひたすらガラケーのテストをしていた。
エクセルに試験項目があって、ただひたすら試験項目を消化していた。

毎日毎日同じような試験をし、2年が過ぎた。
その間何度も転職を考えたけど、スキルが無いなーと躊躇して転職しなかった。

すごくよくない呪いにかけられていたのだけど
「3年は働くべき!」
もうこれほんと悪!
この呪いのせいで大事な2年もしょうもない仕事に費やしてしまった。
あんな仕事にこだわるんじゃなかったなあと、すごく後悔している。


その間、いつ開発現場に行けてもいいように手当り次第勉強をしまくった。
せめて資格を取ろうとして、基本情報、ソフトウエア開発者、オラクルはゴールドまで取った。
(oracle使ったことないのに)
さらに会社の研修施設でJavaの勉強もしてた。

当時の会社がブラック会社だったとはいえ、資格手当が充実してたのがモチベーションだった。
上の3つで毎月3,4万資格手当がでてたような覚えがある。

ちゃっかり社内規定でいくら出るのか調べといて、オラクルゴールドは取得まで20万近くかかるけど
何か月いたら採算とれるなーとか考えて取得してた。


その後社長が不祥事を起こして、あーもうやめようと思って
2社目に転職できた。


転職できた理由は定かじゃないけど、
理系の院卒、資格も取ってた、TOEIC820もやってたからかな思える。
まあ、テスターの経験しかないけど、ギリ(当時)29歳の20代の若手。

転職先もほんとたまたま大手の人材会社のインフラの案件があって
たまたま自分が組み込まれた。

そう思うとやっぱ資格なのかな。
魅せるアピールができてたからよかったのだろう。
当時はね。


しかしながら記事にあるような不運案件はかわいそうとしか言いようない。
自分もちょっと間違えればそっち側になりそうだったと思うと恐怖でしかない。

なんだろね今だと資格よりもプログラミングスクールとかあるし
そういうのやるといいのかな。
サポートが充実してて効果的だろう。

うん俺の答えとしては
しょうもない仕事はさっさとやめて
魅せる学びをやって転職したほうがいいなと感じた記事だった。
全然具体的じゃないね。

魅せる学びって結構大事だなとわかった20代でした。

語学の学習は自分が成長した気分になれる

f:id:suganoo:20180419191013j:plain

気分転換に語学を学んでます。

フランス語、ロシア語、アラビア語です。

フランス語は学生時代にたまたま第二外国語で選んだ言語なのですが
けっこう真面目に勉強してました。
そのままなにもやらずに忘れてしまうのも癪だなあと思い
10年近くだらだらとやってます。

そんでNHKラジオの語学テキストを見たときに
ロシア語を読んでみると「なんか行けそう!」っと勘違いしたので
ロシア語もほそぼそとやってます。

あの巻き舌で言うなんとかーちぇとかいう単語とか、聞き心地がなんとも楽しいんですね。


またフランス以外にフランス語が通じる国と言えばアフリカなのですが
北アフリカの国ではフランス語とアラビア語公用語になってることが多い。

単語的にも共通するのもいくつかあるそうです。

そして、あのにょろにょろした文字なんでしょうね?
どういう意味なんだろっと興味がわいてきてしまったので
アラビア語も始めてしまいました。

それにアラビア語を話せる人は4億人もいるのに
そんなに日本ではやってる人が少ないようにも見えるので
それも動機。

やっとこさとこアラビア文字が読めるようになってきた。

語学の勉強楽しい

語学の学習っていいですよね。

なにがいいかって、ただテキストを読んで少しでも単語や格変化を覚えれば頭がよくなった気になれるところ。

そんな覚える作業なんて数分、数十分でできるし、そんだけでちょっとした達成感が味わえる。


逆に通勤中に数学とかプログラミングとかの本を読んでても
(数学)「わかんねーーーー。。なんでこんな式展開になるんだよ。。。」(10分以上悩む)
(プログラミング)「なるほど、あれ、でも手元にターミナルないから試せない!
やってみたけど知らんエラーが出まくる」(数時間経つ。。)

とかなって、徒労に終わることが多い。

この徒労感がなんともつまらないんですよ。


ただデメリットとして
語学の学習がはまってくると
やらなきゃいけない/やるべきプログラミングなどの学習がどんどんおざなりになってきてしまうところだ。

最近は通勤時間がほとんど語学のテキストを読んでしまっている。
そんなことやってる場合じゃないんだよなあ。

んー悩ましい



まあ英語以外の第二言語も学ぶと楽しいですよというお話

こういうサイトを参考にしてみるといいかも
www.weforum.org

「Linux のしくみ」を読んでみたけどかなりいい本

[試して理解]Linuxのしくみ ~実験と図解で学ぶOSとハードウェアの基礎知識

[試して理解]Linuxのしくみ ~実験と図解で学ぶOSとハードウェアの基礎知識

linux の中身を理解するのはかなりややこしい。
そんな本はないなと思ってたけどありました。

思い起こせば10年以上前、自分で古いノートPC買って
Ubuntuとか入れてみたなあ。

そんで、よしカーネルを理解しよう!と思って
カーネル関係の本を読んで挫折した覚えがよみがえってきます。

Linuxカーネル2.6解読室

Linuxカーネル2.6解読室

Linuxカーネル解析入門 (I・O BOOKS)

Linuxカーネル解析入門 (I・O BOOKS)

↑この本読んで挫折した。いい本ではあるけど。


インフラの仕事をしてると、障害で
「あれメモリが足りないんじゃ?」とか起きてて
先輩がメモリのキャッシュをとばしたりしてて解消してたことがありました。

echo 3 > /proc/sys/vm/drop_caches

こんなコマンドもなにやってんのかなーと疑問に思ってました。

そんなところの、キャッシュメモリやページキャッシュの内容が書かれてたりします。


また以前に紹介したこの本にもメモリのところは書かれてます。
suganoo.hatenablog.com



またタスクスケジューリングのところは
Goで並列処理を考えるときのCPU数の検討で役に立ちました。


今回もおすすめです

「プログラミング言語 Go」を読んでみた

えーっとしばらくぶりに更新します。

サボってました。

いろんな読みたい本を読んでたり、子育てや家事をやってると
あっという間に一週間が経ち一か月が経ってしまうなあ。

今回もGo言語の本を読んでみました。

プログラミング言語Go (ADDISON-WESLEY PROFESSIONAL COMPUTING SERIES)

プログラミング言語Go (ADDISON-WESLEY PROFESSIONAL COMPUTING SERIES)

Go言語の本でいいのないかなとググってみると
いろんなところで、海外のサイトでも、この本が紹介されてました。

で また会社の上司に買って―とお願いして買ってもらいました。

この本は約400ページをボリュームがあるものの
Goで必要にな内容が大体のってます。

特に自分のような初心者には、go test? ベンチマーク
とかいった機能も使い方含めて説明があります。

前半は型などの説明で退屈です。
ですが、インターフェーや、関数値の扱い方もきちっと説明されてて
後半からほーほーふむふむとなってきておもしろくなり
理解を深めるにはとてもいい内容が書かれてます。

時間があったら、サンプルコードを写経して
テストとかベンチマークテストとかやってみたかった。

あと rune 型?なんだこれ、初めて聞いた型でした。
もうちょっと勉強しなきゃなあ。

かなりおすすめ。

プロセスの並列とCPUの効率性

Goでプログラムを書くと処理が早い。

ファイル処理のプログラムを書いていたのだけど
1ファイルの変換プログラムを書いたら、そのまま並列処理をさせようと設計検討をしていた。

そしたら上司から「順番は意識しなくていいのだから、1CPUで1ファイル処理させるようにしてから並列させてスループットを上げてね」と言われた。

何を言ってるのだろうと思ったけど、新しい知見が理解できたのでメモしておく。

普通のプログラムはCPUを全部使う

プログラムを実行させるとそのプログラムを終わらせるために全CPUを使って処理を行う。

ターミナルでtopコマンドを実行してみよう。

top

このとき

top -d1

とかしてやれば、1秒ごとに更新してくれる。

そんで「1」を押してみるとCPUごとの使用率が表示される。

f:id:suganoo:20180222190857p:plain

この状態のままなんかプログラムを実行すると
うわーっと全コアの使用率が上がってきて、全CPUが使われるのがわかると思う。

f:id:suganoo:20180222190847p:plain

並列化してみる

でこのファイル変換処理プログラムを並列実行させてみた。

自分がやったのは goroutine でスレッド作って
それぞれの中で exec.Command(ファイル変換処理).Run() を実行して、変換処理を並列化させてみた。

もちろん1プロセスで全CPUコア使ってるのだから
並列化するとさらにもっと全CPUを使う。

CPU使用数を固定する

goにはCPU使用数を決めてくれる便利な関数がある。

import "runtime"

func main() {
        runtime.GOMAXPROCS(1)  // <---- CPU数を指定できる
.....
}

runtime の runtime.GOMAXPROCS(1) を使うとCPU使用数を固定してくれるそうだ。

CPU使用数を固定して並列化

この設定をファイル変換処理プログラムに入れて並列処理させた。

するとCPUはちゃんと1コアごとに処理して並列処理してた。
f:id:suganoo:20180222190839p:plain

処理性能はどうなった

こんな設定を入れたんだからスループットはどうなったの?が大事なところ。

f:id:suganoo:20180222170609p:plain

こんな風になって割り込みが減るから効率化すると思ってたんだけど

結論として、あんまり変わらなかった。
でもCPU使用率は10%近く下がった。

条件を述べてなかったので書いておく
※ごめんなさい。あまり詳しく書けないです。

CPUコア数 32 (論理CPU:32, 物理CPU:16)
全ファイル処理行数 数億行
ファイル数 んーごめんわすれた。。。1000~2000ファイル?数十万行/ファイルだった気がする

もともと1ファイルの処理性能として

全コア使用 1コア固定
処理時間 22秒 80秒
CPU使用率 13% 3%

だった

並列化して全データを処理した結果が下記
(いくつかのケースで検証したけど抜粋)

並列数 CPU使用率 処理時間
全コアで処理 6パラ 70% 130分
1コア/1プロセスで処理 20パラ 62% 133分

↑CPU使用率を同じくらいにしようとした。

結局のところスループットはちょっと落ちたのだけど
CPU使用率が10%近く下がっていた。

個人的には「おおーめっちゃスループット出てる!」とか言いたかったけど、そうでもなかったのが残念。

# そもそもなんだけど、両ケースではファイル変換ライブラリに与えるパラメータ値も違うので正しく比較できないが、あんまり変わらなかったってことが言えればいいと思ってます。。。

並列数は物理CPU数以下がいい

この本を読み返してみるとこんなことが書いてあった。並列数を変えてやってみました。
suganoo.hatenablog.com

P246
Go 1.5からは、デフォルトでruntime.GOMAXPROCS()が設定されるようになったので、特別な場合を除いてわざわざ設定する必要はありません。しかし、最速を狙おうとすると、このデフォルト値の半分に設定するほうがスループットが上がる場合があります。現代のCPUのいくつかは、余剰のCPUリソースを使って1コアで2余剰のCPUリソースを使って1コアで2つ以上のスレッドを同時に実行する機構(ハイパースレッディングやSMT(Simultaneous Multi-Threding))を備えています。そのような機構を利用している場合、1コアで2つのヘビーな計算を同時に実行すると、CPUコアのリソースを食い合ってパフォーマンスが上がらないことがあります。

へーへーへー!!


こんなところをたまたま見つけたので並列数をいくつか変えてやってみました。

ここで書いてないんだけど1コア/1プロセスの条件下で並列数を変えて実施したところ、確かに16パラ数で実施した場合の1プロセスあたりの処理性能がが一番よかった。

物理コア数以上の並列数を実行すると1プロセスあたりの処理行数が下がっていることがわかりました。

反省点とかまとめとか

  • コア数固定で並列数をあげるとスループットはどうなるかわからないけど、CPU効率は良くなりそう。
  • そもそもサーバーのスペックが良すぎるから、あまり差が出なかったのではと思ってる。
  • 1コア/1プロセスで並列化させるとCPU使用率が比例するから推測しやすく、かけ算するだけで良い。
  • なんかもうちょっと使い方をよくすればもっとスループットが出そうな気がする。

ひとまずここまで。

Goでロガーを作ってみた

Goでロガーを使おうとするとなかなかいいのがない。

logパッケージのやつをそのまま使おうとするとなんか物足りなく使いにくい。
誰かが作ったやつも使いにくい。

blog.hde.co.jp

こういうのあるみたいだけどなんかしっくりこない。。。

なのでlogパッケージをもとにしてラップして作ってみた。
もともとpythonやっててloggingをよく使ってたので
それに近いものを想定してみた。

github.com


いろいろログに出てくるんだけど
どの行どの関数で呼び出されたかも出力されるようにしてみた。


ちょっとまだQiitaとかは怖いので、こっそりここで告知。

もうちょっと修正したらQiitaにも書いてみようかな。

参考ページ
stackoverflow.com
sgykfjsm.github.io
qiita.com


P.S
Qiitaに投稿してみた。
内容はおんなじなんだけど。

qiita.com