読書リスト2017
あっと言う間すらないほど早い一年でした。2017年版です。
- チームが機能するとはどういうことか
- Webを支える技術
- 大規模開発サービス技術入門
- Webサービスの作り方
- まつもとゆきひろ 言語の仕組み
- ゼロから作るDeep Learning
- Server-Side Swift
- きつねさんでもわかるLLVM
- 開眼!JavaScript
- JavaScript本格入門
- Reactビギナーズガイド
- ふつうのLINUX
- 新しいLinuxの教科書
- プロになるためのWeb技術入門
- できるPRO Apache Webサーバー
- Real world http
- 計算理論の基礎
- オペレーションシステムの仕組み
- JavaScriptデザインパターン
- 最短経路の本
- アルゴリズムサイエンス 出口からの超入門
- たった2日でわかるLinux
- PHPはどのように動くのか
- プログラミングコンテストチャレンジブック
- アルゴリズムクイックリファレンス
- 達人に学ぶSQL徹底指南書
- 達人に学ぶDB設計徹底指南書
- The Go Programming Language
- SQLパズル
- プログラマのためのSQL
- SQLアンチパターン
計31冊(減ってるやん。。。)
前半は相変わらず乱読を続けていましたが、秋頃から一つのテーマを掘り下げるスタイルにしました。 こちらの方がいろんな知識を線で捉えられるため体系的に学びやすいと感じているのでとりあえず続けてみようと思います。
春から夏にかけてJavaScriptに興味が湧いたため手をつけていたのですが、仕事で使わないだけでなくプライベートで何かを作る、ということもしなかったため中途半端な知識になってしまったのが残念です。反省。
今は「トレンドを追うよりもコンピュータサイエンスに近いところを学んで足腰を鍛えることを優先した方が後々効率が良いのではないか」という気がしているので、以前よりもだいぶ慎重に読む本を選んでいます。
昨年「2017年学びたいこと」として
をあげていました。達成度は30%以下です。反省。
来年は
- デザインパターン
- OS、言語処理系
- デザイン
あたりを中心に読みたいなと思っています。
また、最近こちらのエントリを読んで感心しました。
「より効率的な読書法」も同時に求めていきたいと思います。
Varnishについて
今週FastlyのStockholm(BMA)で障害が発生1し、私たちのサイトも影響を受けました。その際出てきた「varnish」というミドルウェアについて調べたときのメモです。
Varnishとは
Varnish Cache is a web application accelerator also known as a caching HTTP reverse proxy.
- HTTPレベルでキャッシュを行うHTTPアクセラレータ。
- カーネルの機能を最大限利用することで高速化を図っている。
- ディスクへのデータ書き込みをデフォルトでは一切しないので、プロセス終了時に全てのキャッシュが消える。
- 設定はVCL(Varnish Configuration Language)というDSLで記述する。動的に変更可能。
- ログもデフォルトではファイルに書き込まれない。
- Fastlyの中心技術2。各リージョンにVarnishキャッシュサーバを置いていると雑に考えても間違いではなさそう。
- SSLが使えないのでnginxを前に置く構成が多いらしい。
動かしてみる
varnishをnginxの手前に置いて、nginxのindex.htmlをvarnish経由で返してみる。
参考記事: Getting Started with Varnish Cache
環境
1. コンテナの起動 3
$ docker run --privileged -d -p80:80 --name=varnish centos /sbin/init
2. nginxのインストール&起動 4
$ sudo vi /etc/yum.repos.d/nginx.repo
[nginx] name=nginx repo baseurl=http://nginx.org/packages/mainline/centos/7/$basearch/ gpgcheck=0 enabled=1
$ yum install -y nginx $ systemctl start nginx
3. Varnish Cashのインストール
$ yum install -y epel-release $ yum install -y varnish
4. nginxのポートを8080に変更
etc/nginx/conf.d/default.conf
server { listen 8080; ... }
リロード
$ systemctl reload nginx
5. varnishのポートを80に変更
etc/varnish/varnish.params
VARNISH_LISTEN_PORT=80
起動
$ systemctl start varnish
6. アクセスしてみる
$ curl -I http://localhost HTTP/1.1 200 OK Server: nginx/1.13.6 Date: Sun, 19 Nov 2017 10:46:05 GMT Content-Type: text/html Content-Length: 612 Last-Modified: Tue, 10 Oct 2017 15:59:40 GMT ETag: "59dcee6c-264" X-Varnish: 22 20 Age: 3 Via: 1.1 varnish-v4 Connection: keep-alive
2回目アクセス以降X-Varnish
の値が2つ返っていればキャッシュされている5。
また、nginxのアクセスログに2回目以降のアクセスログが残らないことも確認できた。(キャッシュ間隔のデフォルトは5分。)
疑問
- (リバースプロキシとしている)nginxでも同じことができるのではないか。
- わざわざnginxの後ろにVarnishを置く理由。
参考
JSON-RPCについて
JSON-RPCについて調べた際のメモです。
特徴
JSON-RPC is a stateless, light-weight remote procedure call (RPC) protocol.
- データのエンコードにJSONを利用したRPC(Remote Procedure Call)1プロトコルの一種。
- レスポンスを期待しない「通知」、複数の呼び出しを一度に行う「Batch」が可能。
- リクエスト、レスポンスのjsonに含めるべきフィールドが決められており(プロトコルなので)、それを満たしさえすればよい。
- HTTPメソッドは全てPOSTとするのが通例。
リクエスト
以下、例は主にJSON-RPC 2.0 Specificationから拝借いたしました。
- jsonrpc [string]: JSON-RPCのバージョン(現在2.0)
- method [string]: 呼び出したいメソッド名
- params [array|object]: メソッドの引数(単純に列挙する場合はarray、ラベルを使う場合はobject)
- id [string|int]: リクエストを識別するID、レスポンスに同じ値が含まれる、よってBatch(後述)で送ってもどのリクエストに対するレスポンスかを識別できる
{ "jsonrpc": "2.0", "method": "subtract", "params": [42, 23], "id": 1 }
ラベル付き
{ "jsonrpc": "2.0", "method": "subtract", "params": { "subtrahend": 23, "minuend": 42 }, "id": 3 }
レスポンス
成功時:
失敗時:
errorのフォーマット
- code [int]: エラーコード、あらかじめ定義されている → error object
- message [string]: エラーメッセージ
- data [any]: 追加情報用のフィールド、型の指定もなく、省略も可能
成功時:
{ "jsonrpc": "2.0", "result": 19, "id": 1 }
失敗時:
{ "jsonrpc": "2.0", "error": { "code": -32601, "message": "Method not found" }, "id": "1" }
通知
リクエスト時にIDフィールドを省略すると、レスポンスを期待しないと解釈され、何も返ってこない。これを「通知」と呼んでいる。
{ "jsonrpc": "2.0", "method": "update", "params": [1,2,3,4,5] }
Batch
トップレベルを配列にし、リクエストを複数一気に送ることができる。
リクエスト:
[ {"jsonrpc": "2.0", "method": "sum", "params": [1,2,4], "id": "1"}, {"jsonrpc": "2.0", "method": "notify_hello", "params": [7]}, {"jsonrpc": "2.0", "method": "subtract", "params": [42,23], "id": "2"}, {"foo": "boo"}, {"jsonrpc": "2.0", "method": "foo.get", "params": {"name": "myself"}, "id": "5"}, {"jsonrpc": "2.0", "method": "get_data", "id": "9"} ]
レスポンス:
[ {"jsonrpc": "2.0", "result": 7, "id": "1"}, {"jsonrpc": "2.0", "result": 19, "id": "2"}, {"jsonrpc": "2.0", "error": {"code": -32600, "message": "Invalid Request"}, "id": null}, {"jsonrpc": "2.0", "error": {"code": -32601, "message": "Method not found"}, "id": "5"}, {"jsonrpc": "2.0", "result": ["hello", 5], "id": "9"} ]
例
GoでJSON-RPCを扱う代表的なパッケージは以下の3つ
- jsonrpc - The Go Programming Language
- json2 - Gorilla, the golang web toolkit
- GitHub - osamingo/jsonrpc: The jsonrpc package helps implement of JSON-RPC 2.0
【思ったより手間取っているので追記予定】
疑問
- JSON-RPCを使う理由
- 一般的なidの割り振り方
参考
ISUCONカンニングペーパー
【10/23追記】
残念ながら本選に出場することはできませんでした。
インデックス貼ったりN+1を直したりはできたのでせめて最後にスコアを残したかったと後悔しています。
とはいえ8時間があっという間に感じるくらい楽しかったです。 夜中の2時のサイクリングも最高にエキサイティングでした。
準備不足につきます。 来年こそは本選出場できるように頑張ります。
サーバーの状態確認コマンド群
pstree
ps auxwf
top
htop
dstat -ta
glances
ユーザーの追加
adduser username
usermod -aG sudo username
git
git init git add . git commit -m "first commit"
ファイルの転送
remote → local
# file scp your_username@remotehost.edu:foobar.txt /some/local/directory # directory scp -r your_username@remotehost.edu:/some/remote/directory/foo bar
local → remote
# file scp foobar.txt your_username@remotehost.edu:/some/remote/directory # directory scp -r foo your_username@remotehost.edu:/some/remote/directory
ディレクトリのときは
local$ tar -czvf local.tar directory/ local$ scp local.tar user@remote:/directory ssh user@remote remote$ tar -xzvf local.tar
がよい。
言語の切り替え
systemdに登録されたサービスは /etc/systemd/system/
以下。
sudo -s systemctl stop XXX systemctl start YYY journalctl -f
netdata の設定
bash <(curl -Ss https://my-netdata.io/kickstart-static64.sh)
して <host>:19999
にアクセス。
alp の設定
1.Releases · tkuchiki/alp · GitHub で最新版を確認する
2.インストール
wget https://github.com/tkuchiki/alp/releases/download/v0.3.1/alp_linux_amd64.zip
unzip alp_linux_amd64.zip
sudo install ./alp /usr/local/bin
3.access.log の設定 /etc/nginx/nginx.conf を以下のように修正
... http { log_format ltsv "time:$time_local" "\thost:$remote_addr" "\tforwardedfor:$http_x_forwarded_for" "\treq:$request" "\tstatus:$status" "\tmethod:$request_method" "\turi:$request_uri" "\tsize:$body_bytes_sent" "\treferer:$http_referer" "\tua:$http_user_agent" "\treqtime:$request_time" "\tcache:$upstream_http_x_cache" "\truntime:$upstream_http_x_runtime" "\tapptime:$upstream_response_time" "\tvhost:$host"; access_log /var/log/nginx/access.log ltsv; } ...
4.再起動
rm /var/log/nginx/access.log && systemctl reload nginx
5.実行
alp --sum -r -f /var/log/nginx/access.log --aggregates='/keyword/.*'
slow query
1.my.conf の設定
以下を追記
[mysqld] ... slow_query_log = 1 slow_query_log_file = /var/log/mysql/slow.log long_query_time = 0
2.mysql、アプリの再起動
systemctl restart mysql systemctl restart XXX
3.percona-toolkit のインストール (Debian8: jessie)
wget https://www.percona.com/downloads/percona-toolkit/3.0.3/binary/debian/jessie/x86_64/percona-toolkit_3.0.3-1.jessie_amd64.deb
apt install libdbd-mysql-perl libdbi-perl libio-socket-ssl-perl libnet-ssleay-perl libterm-readkey-perl
dpkg -i percona-toolkit_3.0.3-1.jessie_amd64.deb
4.解析
pt-query-digest --limit 10 /var/log/mysql/slow.log
再起動用のスクリプト
#!/bin/sh set -e now=`date +%Y%m%d-%H%M%S` mv /var/log/nginx/access.log /var/log/nginx/access.log.$now systemctl reload nginx mv /var/log/mysql/slow.log /var/log/mysql/slow.log.$now mysqladmin -uisucon -pisucon flush-logs systemctl restart XXX journalctl -f
静的データのnginxでの配信
location / {}
の前に、
location ^/(img|css|js|favicon.ico) { root /path/to/static/files; }
my.cnf
innodb_buffer_pool_size = 1G innodb_flush_log_at_trx_commit = 0 innodb_flush_method=O_DIRECT
nginx.conf
とりあえず、
# Worker connections events { worker_connections XXX; use epoll; multi_accept on; } http { ... sendfile on; tcp_nopush on; tcp_nodelay on; etag off; ... }
worker_connections = ulimit -n
あとは How to Configure nginx for Optimized Performance
autostart (with sysetmd)
check
systemctl is-enabled <SERVICE_NAME>
enable
systemctl enable <SERVICE_NAME>
参照
- ISUCON 夏期講習 2017 を開催しました(当日の資料あり) : ISUCON公式Blog
- ISUCON4 予選でアプリケーションを変更せずに予選通過ラインを突破するの術 - Hateburo: kazeburo hatenablog
- How to Configure nginx for Optimized Performance
- How To Create a Sudo User on Ubuntu [Quickstart] | DigitalOcean
雑記
systemctl restart
とsystemctl reload
の違い
reload: Unitに対して設定ファイルの再読み込みを促す。(対象のUnitがreload動作に対応している必要がある)
restart: 起動中のUnitを停止後、起動(stop -> start)する。対象のUnitが停止中である場合、起動操作のみ実施する。
【メモ】Redisについて
Redisについての雑多なメモです。
特徴
Redis is an open source (BSD licensed), in-memory data structure store, used as a database, cache and message broker.
- Key-Valueストレージで、NoSQLに分類される
- そういう文脈上キャッシュというよりはデータストレージ
- 最大の特徴は構造を持つデータ(リストやオブジェクト)をそのまま保存できること
- パフォーマンスはmemcachedにremarkably similarらしい
- データは定期的にディスクに保存されるためサーバが落ちてもデータが残るし、再起動時にはロードされる
- データのサイズに制限はないが、全体サイズがメモリ容量に収まる必要がある、あるいは削除の設定をする必要がある
導入
// ダウンロード
$ wget http://download.redis.io/redis-stable.tar.gz
$ tar xzf redis-stable.tar.gz
$ cd redis-stable
// ビルド
$ make
// 起動
$ src/redis-server
PHPでの利用方法
PHPでRedisを利用する際は、以下の2つがメジャー。
どちらのクライアントも基本的にRedisのコマンド名と同じメソッドが定義されているので利用法に大きな差異はないが導入方法が異なる。また、phpredisはextensionなのでpredisよりも高速で動作することが予想される。
predis
ライブラリなのでcomposer経由でインストール。
{ "require": { "predis/predis": "^1.1.1" } }
アプリケーション側からは以下のように利用する。
<?php require __DIR__ . '/../vendor/autoload.php'; use Predis\Client as PredisClient; try { $redis = new PredisClient(); } catch (Exception $e) { die($e->getMessage()); } // 値の設定 $redis->set('message', 'Hello world'); // 値の取得 $value = $redis->get('message'); print($value); // Hello world
phpredis
こちらはextensionとなっているので、
ダウンロード & ビルド → php.iniにモジュールの登録
の手順を踏む必要がある。
- ダウンロード & ビルド
$ git clone git://github.com/nicolasff/phpredis.git $ cd phpredis $ phpize // エクステンションを追加する際に,phpを最初からコンパイルし直す必要なく,追加するためのコマンド(*) $ ./configure $ make && make install
(*) Redisの使い方
- モジュールの登録
ビルドされたredis.so
というファイルをphpのextensionが入っているディレクトリにコピーし、php.iniに登録する。
$ cp modules/redis.so {php-config–extension-dir} $ sudo echo “extension=redis.so” > /etc/php5/conf.d/redis.ini
アプリケーション側からは以下のように利用する。
<?php $redis = new Redis(); // extensionとして登録しているからロードせず使える $redis->connect('127.0.0.1',6379); $redis->set('dog', 'bow-bow'); $res = $redis->get('dog'); echo $res . PHP_EOL; $redis->close();
気になる点
参考
【2016】読書リスト
年の瀬を感じる今日この頃。
備忘録を兼ねて、2016年に読んだ技術書・参考書を一覧にまとめました。
参考にしたサイト
読む本は主に以下の二つのQiitaエントリーを参考にしています。
エントリの筆者の二人に感謝申し上げます🙇
2016読書リスト(計:45冊)
※読んだ順序はこの通りではありません。
振り返り
振り返ってみると前半の方は「え、これ読んだの今年!?」っていうくらい昔のことに感じます。
中にはあまり面白くなかったもの、ちゃんと理解できなかったものもありますが、
数多くの好奇心刺激する本に出会えて楽しかったです。
幅広い知識に触れることができた一方、どれも実用レベルでないのは残念なところです。
結局手を動かさないと使える知識にならないんだなと実感しました。
来年は
本を選ぶ上で特に戦略は持っておらず、興味の向くままに選んでいます。
戦略があった方がいい気もするし、このスタンスに特に自信があるわけではありませんが、
来年もこのスタイルで読む本を選んでいきたいと思います。
みなさんどのように本を選んでいるのでしょうか。
来年は実務で使う技術に加え、
などに挑戦したいなーと思います。
オススメの書籍、書籍を紹介しているサイト等あれば是非是非教えてください🙇
FrenchKit
先週末9/23,24にフランスのパリで行われたFrenchKitに参加して来ました。
2日間のうち1日目の23日はトークのみ、2日目24日はライブコーディング及びクラスルーム、クロージングというコンテンツでした。
コンテンツ
全てを見つけることはできませんでした。。(Realmで公開されるのかな?)
【LT】Human Engineering
スピーカー:Jeremie Giraultさん(@kamidude)
github.com
Designing Pro Apps
スピーカー:Piet Brauerさん(@pietbrauer)
speakerdeck.com
github.com
【LT】Building your UI Developer's Toolbox with Playground
スピーカー:Hugues Bernet-Rollandeさん(@rompelstilchen)
speakerdeck.com
github.com
Reactive Programming with RxSwift
スピーカー:Florent Piletさん(@fpillet)
Mixins vs Inheritance
スピーカー:Olivier Haligonさん(@aligatr)
speakerdeck.com
【LT】Swift script all the things!
スピーカー:Roy Marmelsteinさん(@marmelroy)
github.com
(未更新ですが、後々更新されることと思います。)
Swift Evolution - 140 proposals in 30 minutes
スピーカー:Jesse Squiresさん(@jesse_squires)
speakerdeck.com
github.com
Optimizing Your App's Performance - How to Do It Right
スピーカー:Bruno Virletさん(@bvirlet)
【LT】Swift Package Manager
スピーカー:JC Pastantさん
Core Data - it's not dead yet
スピーカー:Abizer Nasirさん(@abizern)
speakerdeck.com
End-To-End Application Development with Swift
スピーカー:Chris Baileyさん(@Chris__Bailey)
An Overview of Verification Techniques Today
スピーカー:Fabrice Kordonさん(@fabricekordon)
Extending Xcode
スピーカー:Boris Buglingさん(@neonacho)
Launch Arguments: the Mysteries
スピーカー:Marin Usaljさん(@_supermarin)
Live Streaming Swift Talk
スピーカー:Chris Eidofさん(@chriseidhof)&Florian Kuglerさん
SortDescriptorの話。(関連:http://chris.eidhof.nl/post/sort-descriptors-in-swift/)
MVC Supercharged
スピーカー:Grégoire Lhotellierさん(@greg3z)&Jéremie Giraultさん(@kamidude)
github.com
Classroom
各ブースに分かれてのハンズオンでした。 ソースコードはこちら。
- RxSwift Hands-on(Florent Pilletさん@fpillet)
- Core Data Hands-on(Abizer Nasirさん@abizern)
- Introduction to Bluetooth LE and IoT(Hugues Bernet-Rollandeさん@rompelstilchen)
- DTrace: Beyond Instruments(Frank Lefebvreさん)
- Accessibility for iOS Applications: the Main APIs, the Best Practices and Beyond the Technique(Amadou Amath Ndiayeさん)
- Reactive Programming with Realm(Marius Rackwitzさん)
- Server-Side Swift Hands-on(Chris Baileyさん@Chris__Bailey)
How to Become an iOS Full-stack Developer in Just 60 Minutes
ゲーム大会with🍷&🧀
食事
初日朝
初日昼
初日夜
2日目🍷&🧀
おすすめトーク
Designing Pro Apps
git2goを作ったpietさんによるiPad Proを開発機として使うお話。
Playgroundも使えるようになったし、休日に作業したい時とかアリかも。
そのほかいいiPad Proアプリの作り方など。
Swift Evolution - 140 proposals in 30 minutes
try!swiftでもお話しされたJesseさんによるSwiftEvolutionのプロポーザルを解析されたお話。
Q&Aの「Erica Sadunさんは実在するんですか?」がウケてた。
[Optimizing Your App's Performance - How to Do It Right]
画像のフィルタリングを最適化する話。
標準のAPIからCを経てアセンブリ言語まで。結果は、アセンブリまで最適化する必要はないそう。
最近命令セットなどを学んだのでタイムリーで面白かった。
[End-To-End Application Development with Swift]
IBMのChrisさんによるSwiftをサーバーとモバイル両方で使うメリットについてのお話。
前日にKitura1.0がリリースされており、"Server side Swift is getting real"だそうです。
感想
- トーク後の司会役含めた3人でのセッションが面白かった。(Q&A含む)
- 会話の多くはフランス語で行われており、現地の方が多かった様子。
- 男女比は9:1くらいで、パリでもそうなんだなあと。
カンファレンスを口実に海外に行くのは充実した旅行ができるのでオススメです😄。