復旧方法:「dyld: Library not loaded: /usr/local/opt/icu4c/lib/libicui18n.58.dylib」nodeのエラー

Macでnodeを使おうとすると、「dyld: Library not loaded: /usr/local/opt/icu4c/lib/libicui18n.58.dylib」とエラーが出て動かなくなっていたので、以下の方法を試したら復旧した。

brew uninstall –ignore-dependencies node icu4c
brew uninstall –force icu4c
brew install node

これで無事に、nodeが動くようになった。

書籍:『超速!Webページ速度改善ガイド』

超速!Webページ速度改善ガイドは 、Web系エンジニア、デザイナー必読の書だと思います。

とても勉強になり、いろんなページをスライドに書き起こして学びました。

例えばクリティカルレンダリングパス。
ブラウザがロードして描画するまでの関連処理が解説されています。

Google Chrome の DevToolをどのように使用して、どのように使えるのかの解説があります。
何となくで使っていたので知らない機能が多くとても勉強になりました。

まとめ

Webサイトのフロント側の速度改善をする際の手法やツール、ポイントが体系だってまとめられています。
改善するには計測して分析が必要になりますが、
解析ツール・サービスの紹介、DevToolの使い方(何トン買う使ってるけど使いこなせてないって思ってる人は必見)、
そこからどう読み解くのかの解説。

HTTP/1とHTTP/2を踏まえたチューニングポイントの解説。
レンダリングまでの各ターニングポイントとブロッキング、こういう場合はこう回避できるの説明がされています。
全体的に広範囲な内容を取り扱っているので網羅性は十分。
深みはどうしても薄かったり厚かったりしますが、それでも自分で調べられるようになる入り口には立てます。

読み終わった瞬間に自サイトをどう測定したらいいかイメージが持て、
その結果をどう読んで、どんな打ち手があるのかまでは漠然とはしていてもイメージがつかめる。
これはWeb系エンジニア、デザイナー必読の書だと思います。

読んで得られるものがなかったて人は、十分Webページ速度改善のエキスパート側に入ってます。

redash のバックアップをする

redash のデータベースに接続する

次のコマンドで接続します。

sudo -u redash psql -d redash

接続を切るときには次のコマンド。

\q

redash のデータベース容量を確認する

select t1.datname AS db_name, pg_size_pretty(pg_database_size(t1.datname)) as db_size
from pg_database t1
where t1.datname = 'redash'

サーバーのディスク空き容量を確認する

バックアップをする前にサーバーのディスクの空き容量を確認します。

df -hT

データベースのバックアップコマンド

バックアップをします。

sudo -u redash pg_dump redash | gzip > redash_backup.gz

バックアップコマンド

JavaScriptのCPU問題箇所特定ツール:sjsp

はてなの中の人が、Mackerelのフロントエンドの性能チューニングのために作成したsjspが、サーバレスアーキテクチャによる時系列データベースの構築と監視 / Serverlessconf Tokyo 2017dで紹介されていました。

sjspにトランスパイルするだけでCPU boundな処理がわかるそうな。

sjspについては、「シンプルでかつ最高のJavaScriptプロファイラ sjsp を作りました! ― Webアプリケーションが複雑化する中でプロファイラに求められるものとは何か」で説明されています。

こんな感じの結果が出るなんて素晴らしい!

========== SORT BY TIME ==========
time: 30.20sec   count:  71      test6  test.js  (line: 31, col: 18)  function test6() {
time: 16.47sec   count:  41      test7  test.js  (line: 37, col: 18)  function test7() {
time: 15.49sec   count: 133      test4  test.js  (line: 19, col: 18)  function test4() {
time:  5.98sec   count: 216      test1  test.js  (line:  1, col: 18)  function test1() {
time:  4.37sec   count:  18      test5  test.js  (line: 25, col: 18)  function test5() {
time:  3.24sec   count: 512      test3  test.js  (line: 13, col: 18)  function test3() {
time:  0.87sec   count:  67  anonymous  test.js  (line: 49, col: 24)  setInterval(function() {
time:  0.80sec   count:   2      test2  test.js  (line:  7, col: 18)  function test2() {
time:  0.44sec   count:   2  anonymous  test.js  (line: 43, col: 23)  setTimeout(function() {
========== SORT BY COUNT ==========
time:  3.24sec   count: 512      test3  test.js  (line: 13, col: 18)  function test3() {
time:  5.98sec   count: 216      test1  test.js  (line:  1, col: 18)  function test1() {
time: 15.49sec   count: 133      test4  test.js  (line: 19, col: 18)  function test4() {
time: 30.20sec   count:  71      test6  test.js  (line: 31, col: 18)  function test6() {

node_exporter の次期アップグレードで変更になるオプション設定

現時点ではリリースされていないのですが、masterに後方互換のない破壊的変更が入っていますので紹介します。

node_exporterでは、28個のコレクターが既定で有効になっています。
既定で有効になっているコレクターを無効にするには、「–no-collector.<name>」をflagに設定します。

例えば、arpとcpuを無効にするには、オプションに次のように指定します。

./node_exporter –no-collector.arp –no-collector.cpu

また、node_exporterは、既定では無効になっている16個のコレクターがあります。
それらを有効にするには、「–collector.<name>」をflagに設定します。

例えば、logindを有効にするには、オプションに次のように指定します。

./node_exporter –collector.logind

実装

コレクターの実装を見てみましょう。
コレクターをnode_exporterに登録するには、init時に「registerCollector」で登録します。
引数にコレクター名と、デフォルトで有効か無効かと、実装関数を渡します。

func init() {
    registerCollector("bonding", defaultDisabled, NewBondingCollector)
}

collector.go では、配列に実装関数とコレクターフラグ名・有効無効とをそれぞれに格納します。

collectorState[collector] = flag
factories[collector] = factory

後は順次、ループで非同期でコレクターをexecuteしていきます。

// Collect implements the prometheus.Collector interface.
func (n nodeCollector) Collect(ch chan<- prometheus.Metric) {
	wg := sync.WaitGroup{}
	wg.Add(len(n.Collectors))
	for name, c := range n.Collectors {
		go func(name string, c Collector) {
			execute(name, c, ch)
			wg.Done()
		}(name, c)
	}
	wg.Wait()
}