patorashのブログ

方向性はまだない

pgbenchでチューニング前後でベンチマークを取ってみた

PC

  • Lenovo L380 yoga
  • OS: Windows 10 Pro
  • バージョン: 2004
  • CPU: Intel(R) Core(TM) i7-8550U CPU @ 1.80GHz 1.99GHz (4コア8スレッド)
  • メモリ: 32GB

PostgreSQLサーバ

Hyper-VVM上に構築した。

pgbenchを実行した環境

PostgreSQLサーバを複製して作成。ネットワーク越しにpgbenchを実行するための環境。

チューニングした内容

PGTuneで生成したものを利用する。

pgtune.leopard.in.ua

ALTER SYSTEMコマンドのほうを利用する。これを使うと、postgresql.confを編集せずに、postgresql.auto.confが更新され、次回からこれが反映される。しかし、実行しただけでは反映されていないのでPostgreSQLの再起動が必要。

# DB Version: 11
# OS Type: linux
# DB Type: web
# Total Memory (RAM): 1 GB
# CPUs num: 1
# Connections num: 100
# Data Storage: ssd

ALTER SYSTEM SET
 max_connections = '100';
ALTER SYSTEM SET
 shared_buffers = '256MB';
ALTER SYSTEM SET
 effective_cache_size = '768MB';
ALTER SYSTEM SET
 maintenance_work_mem = '64MB';
ALTER SYSTEM SET
 checkpoint_completion_target = '0.7';
ALTER SYSTEM SET
 wal_buffers = '7864kB';
ALTER SYSTEM SET
 default_statistics_target = '100';
ALTER SYSTEM SET
 random_page_cost = '1.1';
ALTER SYSTEM SET
 effective_io_concurrency = '200';
ALTER SYSTEM SET
 work_mem = '1310kB';
ALTER SYSTEM SET
 min_wal_size = '1GB';
ALTER SYSTEM SET
 max_wal_size = '4GB';
項目 チューニング前 チューニング後
max_connections 100 100
shared_buffers 128MB 256MB
effective_cache_size 4GB 768MB
maintenance_work_mem 64MB 64MB
checkpoint_completion_target 0.5 0.7
wal_buffers 4MB 7864kB
default_statistics_target 100 100
random_page_cost 4 1.1
effective_io_concurrency 1 200
work_mem 4MB 1310kB
min_wal_size 80MB 1GB
max_wal_size 1GB 4GB
max_worker_processes 8 8
max_parallel_workers_per_gather 2 2
max_parallel_workers 8 8

実行した条件

pgbench -h 192.168.100.2 -p 5432 -U postgres -c 30 -t 1000 -N benchdb

クライアント数を30、トランザクション数を1,000とした。また、実際にWebアプリを想定して頻繁に更新は起きないだろうということで、-Nオプションを追加して実施した。

結果発表!

単位はTPS(including connections establishing)です。

回数 チューニング前 チューニング後
1 806 813
2 775 820
3 789 846
4 751 806
5 753 834
平均 774 823

平均すると50TPSくらい性能が向上した。823 / 774 * 100 = 106.33...なので、6.3%くらいの性能向上だった。

考察

一応、チューニングによって性能向上はしたけれど、劇的という感じには思えなかった。やはりCPUコア数やメモリの量を少なくしているのが響いているのか? CPUコア数を増やしたり、メモリ量を調整してまたチャレンジしたい。

あとpgbenchの他のオプションについてイマイチまだ理解できていないので使ってない。PostgreSQLのslackとかで質問してみるかなぁ…。(Slackをあまり使ってないのでなんとなく苦手意識がある)

もう一つ仮想環境を作って、そこからpgbenchを実行してみた

Hyper-VAmazon Linux2を立ち上げていて、前回はそこでpgbenchを実行してみていた。

patorash.hatenablog.com

pgbenchでtwitterで検索していたら、pgbenchを実行するホストとPostgreSQLが動いているホストが同じ場合、pgbenchにCPUを使われるのでもっと正確なベンチマークが取れないという話を見て、確かになぁ…と思った次第で、ちょっととりあえずもう一台VMを作って、そこから実行してみようと思った。

Hyper-Vの仮想環境を複製する

複製するのは、特にこだわりを持たなければ簡単だった。こだわりというのは、仮想環境のハードドライブをどこに置くか、というところだ。そこさえ気にしなければ、簡単。

複製の準備

まず、複製対象のVMをオフにします。

f:id:patorash:20200813024059p:plain
VMをオフにする。

次に、VMのイメージをエクスポートします。場所は適当に。私はOneDriveにバックアップされると面倒なので、ホームディレクトリ直下に置いた。

f:id:patorash:20200813024703p:plain

これで準備は完了です。

複製する

複製は、先ほどエクスポートしたイメージをインポートするだけですが、インポートウィザードで多少修正します。まずはインポートを選択します。

f:id:patorash:20200813024841p:plain

先ほどエクスポートしたイメージのディレクトリを選択します。

f:id:patorash:20200813025101p:plain

どんどん進めていき、インポートの種類のところで、「仮想マシンをコピーする(新しい一意なIDを作成する)」を選択します。

f:id:patorash:20200813025258p:plain

他は変更なく進めて、最後の「仮想ハードディスクを保存するフォルダを選択します」のところで、デフォルトと違うフォルダを選択します。元のままだと、複製元のVMと同じ名前のハードディスク名になってしまうため、既にあるので作れないと怒られてしまいます。このフォルダに置きたい!というこだわりがなければ、別名のフォルダを作ってしまい、そこに置きましょう。

f:id:patorash:20200813025822p:plain

あとは、確認画面が出るので、問題なければインポートを実行します。VMのインポートなので、そこそこ時間はかかります。

コピーが終わっていれば、終了です。

両方とも立ち上げてみましょう。複製元のVMに固定IPを振っていなければ、問題なく動くかと思いますが、振っている場合は、複製先のVMは他のIPを振りましょう。

もう一台のVMからPostgreSQLに接続する

複製元をプライマリ、複製先をセカンダリと呼ぶことにします。(まだレプリケーションとかしてないけど)

postgresql.confとpg_hba.confを修正していないため、セカンダリからプライマリに接続することができません。以下のようにエラーになります。

[ec2-user@postgres ~]$ psql -h 172.23.59.9 -p 5432 -U postgres benchdb
psql: could not connect to server: Connection refused
        Is the server running on host "172.23.59.9" and accepting
        TCP/IP connections on port 5432?

postgresql.confを修正して、TCP/IP接続可能にする

プライマリ側のpostgresql.confを修正します。場所は/var/lib/pgsql/data/postgresql.confでした。listen_addressesの行のコメントアウトを外し、全てのIPを許可するために*に、portの行のコメントアウトを外しました。

#------------------------------------------------------------------------------
# CONNECTIONS AND AUTHENTICATION
#------------------------------------------------------------------------------

# - Connection Settings -

listen_addresses = '*'          # what IP address(es) to listen on;
                                        # comma-separated list of addresses;
                                        # defaults to 'localhost'; use '*' for all
                                        # (change requires restart)
port = 5432                             # (change requires restart)

change requires restartと書いてあるので、postgresqlを再起動します。

sudo systemctl restart postgresql

pg_hba.confを修正する

ホストベース認証の設定ファイルであるpg_hba.confを修正します。デフォルトだとlocalhostしか許可していません。 今回は、同一サブネットからの接続は全てtrustにしました(勉強用なので!) 最後の行を追加しています。

# TYPE  DATABASE        USER            ADDRESS                 METHOD

# "local" is for Unix domain socket connections only
local   all             all                                     trust
# IPv4 local connections:
host    all             all             127.0.0.1/32            trust
# IPv6 local connections:
host    all             all             ::1/128                 trust
# Allow replication connections from localhost, by a user with the
# replication privilege.
local   replication     all                                     trust
host    replication     all             127.0.0.1/32            trust
host    replication     all             ::1/128                 trust
host    all             all             172.23.48.0/20          trust

ちなみにサブネットマスクの計算は以下のサイトを使いました。

note.cman.jp

pg_hba.confの修正に関しては、再起動は不要なので設定を再読み込みさせます。

pg_ctl reload

接続してみます。

[ec2-user@postgres ~]$ psql -h 172.23.59.9 -p 5432 -U postgres benchdb
psql (11.5)
Type "help" for help.

benchdb=#

できました!

セカンダリからpgbenchを実行する

では、実行してみましょう。

[ec2-user@postgres ~]$ pgbench -h 172.23.59.9 -p 5432 -U postgres benchdb
starting vacuum...end.
transaction type: <builtin: TPC-B (sort of)>
scaling factor: 1
query mode: simple
number of clients: 1
number of threads: 1
number of transactions per client: 10
number of transactions actually processed: 10/10
latency average = 6.123 ms
tps = 163.323153 (including connections establishing)
tps = 179.586074 (excluding connections establishing)

特にまだチューニングもしていないし、pgbench側のオプションも付けていないのですが、TPSが163という結果になりました。

ちなみにプライマリで実行してみた結果はというと…

-bash-4.2$ pgbench -h 127.0.0.1 -p 5432 -U postgres benchdb
starting vacuum...end.
transaction type: <builtin: TPC-B (sort of)>
scaling factor: 1
query mode: simple
number of clients: 1
number of threads: 1
number of transactions per client: 10
number of transactions actually processed: 10/10
latency average = 3.132 ms
tps = 319.238007 (including connections establishing)
tps = 388.040694 (excluding connections establishing)

TPSが319なので、流石に違うホストからのベンチマークよりは速いのかなというところ。とはいえ、これがCPUを食い合ってる状態なので、微妙!

まだ全然チューニングもしていない状態だし、pgbenchのオプションの最適な値もわかっていないけれど、とりあえず今日はここまで。眠い。

pgbenchをとりあえず使ってみた

勉強をしているので、pgbenchを使ってみた。pgbenchはPostgreSQLベンチマークツール。

lets.postgresql.jp

ただし、pgbenchは厳密な意味でのベンチマークツールではありません。TPC(http://www.tpc.org)などで「公式」に認められているような性能測定を行う目的には向いていません。その点はご注意下さい。

とあるので、あくまでも公式ではない点に注意。

yumpostgresql-contribをいれてあるので、pgbenchはもう使える状態になっていた。入ってない場合は入れること。

sudo yum install postgresql-contrib

pgbenchを試す

データベースを作成する

pgbenchを実行するためのデータベースを作成する。postgresユーザになってから作業すると楽。

sudo -i -u postgres

データベースを作る

createdb benchdb

pgbench用にデータベースを初期化する

-iオプションで、初期化される。-sオプションに数字を渡すと、サンプルデータ量が増える。デフォルトで10万件なので、-s 10にすると100万件入る。-fでフィルファクターの値も指定できるらしい。とりあえず最初なので、素のままにする。

pgbench -i benchdb

以下のように、テーブルを再作成してデータを突っ込んで完了。

-bash-4.2$ pgbench -i benchdb
dropping old tables...
creating tables...
generating data...
100000 of 100000 tuples (100%) done (elapsed 0.11 s, remaining 0.00 s)
vacuuming...
creating primary keys...
done.

測定する

以下のコマンドで測定可能。ただし、オプションがない状態だと、ほとんど参考にならない(らしい)。今回はpgbenchがちゃんと動くことを確認するために一旦何もなしで動かす。

pgbench benchdb

結果は以下の通り。

-bash-4.2$ pgbench benchdb
starting vacuum...end.
transaction type: <builtin: TPC-B (sort of)>
scaling factor: 1
query mode: simple
number of clients: 1
number of threads: 1
number of transactions per client: 10
number of transactions actually processed: 10/10
latency average = 3.660 ms
tps = 273.251220 (including connections establishing)
tps = 319.517166 (excluding connections establishing)

TPS(一秒あたりのトランザクション数)の値が、性能を表す。これが高ければ高いほど良い。

項目 項目の説明
scaling factor 1 DBを初期化したときのデータ量。-sの値。デフォルトで1(10万件)
query mode simple クエリモード(simple | extends | prepared)
number of clients 1 同時接続クライアント数
number of threads 1 接続スレッド数
number of transactions per client 10 1クライアント辺りのトランザクション
number of transactions actually processed 10/10 正常終了したトランザクション
latency average 3.660ms 遅延時間
tps(including connections establishing) 273.251220 PostgreSQLに対する接続を確立する時間を含んだTPS
tps(excluding connections establishing) 319.517166 PostgreSQLに対する接続を確立する時間を含まないTPS

オプションを渡すことで様々な条件で検証できる。更新を含むトランザクションを発行するが、更新を含まないようにするオプションもある。参照用DBの場合には有効だ。

また、デフォルトだとpgbenchの条件で作られたテーブル構造でしかテストできないが、テーブル定義と発行したいクエリさえ準備できれば、pgbench経由で検証することが可能らしいので、実際のテーブル定義などを準備して本番に近い形で負荷試験をすることも可能っぽい。ただ、それは準備が相当大変になるだろう…。

どういうふうに検証を進めていけばいいのか?

これが正直わからない。 恐らく、

  1. 想定接続数とトランザクション数を徐々に増やしつつ、トランザクションが全て成功した上で最もTPSが出たところを基本にする。
  2. postgresql.confの項目を1つ修正する。
  3. ベンチマークを取り直す。
  4. TPSが上がったら設定を生かす。そうでなければ違う値にするか元に戻す。

を地道に繰り返すのかなぁ~と思う。

いい方法があれば教えていただきたい。

後日、postgresql.confを修正してからやったものなどを書いてみようと思う。

Amazon Linux2にPostgreSQL11を入れる

Hyper-V環境のAmazon Linux2にPostgreSQLをインストールしようとしたらちょっとハマったのでメモを残す。

Amazon Linux2でyumPostgreSQLを入れようとすると、9.2という古いものが出てくる。

新しいものを入れるには、amazon-linux-extrasを使う。listと打つと、利用可能なものが表示される。postgresqlも9.6や10や11などが準備されている。今回は11を入れた。

[ec2-user@postgres ~]$ amazon-linux-extras install postgresql11
[ec2-user@postgres ~]$ amazon-linux-extras list
  0  ansible2                 available    \
        [ =2.4.2  =2.4.6  =2.8  =stable ]
  2  httpd_modules            available    [ =1.0  =stable ]
  3  memcached1.5             available    \
        [ =1.5.1  =1.5.16  =1.5.17 ]
  5  postgresql9.6            available    \
        [ =9.6.6  =9.6.8  =stable ]
  6  postgresql10             available    [ =10  =stable ]
  8  redis4.0                 available    \
        [ =4.0.5  =4.0.10  =stable ]
  9  R3.4                     available    [ =3.4.3  =stable ]
 10  rust1                    available    \
        [ =1.22.1  =1.26.0  =1.26.1  =1.27.2  =1.31.0  =1.38.0
          =stable ]
 11  vim                      available    [ =8.0  =stable ]
 13  ruby2.4                  available    \
        [ =2.4.2  =2.4.4  =2.4.7  =stable ]
 15  php7.2                   available    \
        [ =7.2.0  =7.2.4  =7.2.5  =7.2.8  =7.2.11  =7.2.13  =7.2.14
          =7.2.16  =7.2.17  =7.2.19  =7.2.21  =7.2.22  =7.2.23
          =7.2.24  =7.2.26  =stable ]
 17  lamp-mariadb10.2-php7.2  available    \
        [ =10.2.10_7.2.0  =10.2.10_7.2.4  =10.2.10_7.2.5
          =10.2.10_7.2.8  =10.2.10_7.2.11  =10.2.10_7.2.13
          =10.2.10_7.2.14  =10.2.10_7.2.16  =10.2.10_7.2.17
          =10.2.10_7.2.19  =10.2.10_7.2.22  =10.2.10_7.2.23
          =10.2.10_7.2.24  =stable ]
 18  libreoffice              available    \
        [ =5.0.6.2_15  =5.3.6.1  =stable ]
 19  gimp                     available    [ =2.8.22 ]
 20  docker=latest            enabled      \
        [ =17.12.1  =18.03.1  =18.06.1  =18.09.9  =stable ]
 21  mate-desktop1.x          available    \
        [ =1.19.0  =1.20.0  =stable ]
 22  GraphicsMagick1.3        available    \
        [ =1.3.29  =1.3.32  =1.3.34  =stable ]
 23  tomcat8.5                available    \
        [ =8.5.31  =8.5.32  =8.5.38  =8.5.40  =8.5.42  =8.5.50
          =stable ]
 24  epel                     available    [ =7.11  =stable ]
 25  testing                  available    [ =1.0  =stable ]
 26  ecs                      available    [ =stable ]
 27  corretto8                available    \
        [ =1.8.0_192  =1.8.0_202  =1.8.0_212  =1.8.0_222  =1.8.0_232
          =1.8.0_242  =stable ]
 28  firecracker              available    [ =0.11  =stable ]
 29  golang1.11               available    \
        [ =1.11.3  =1.11.11  =1.11.13  =stable ]
 30  squid4                   available    [ =4  =stable ]
 31  php7.3                   available    \
        [ =7.3.2  =7.3.3  =7.3.4  =7.3.6  =7.3.8  =7.3.9  =7.3.10
          =7.3.11  =7.3.13  =stable ]
 32  lustre2.10               available    \
        [ =2.10.5  =2.10.8  =stable ]
 33  java-openjdk11           available    [ =11  =stable ]
 34  lynis                    available    [ =stable ]
 35  kernel-ng                available    [ =stable ]
 36  BCC                      available    [ =0.x  =stable ]
 37  mono                     available    [ =5.x  =stable ]
 38  nginx1                   available    [ =stable ]
 39  ruby2.6                  available    [ =2.6  =stable ]
 40  mock                     available    [ =stable ]
 41  postgresql11=latest      enabled      [ =11  =stable ]
 42  php7.4                   available    [ =stable ]
 43  livepatch                available    [ =stable ]
 44  python3.8                available    [ =stable ]
 45  haproxy2                 available    [ =stable ]

postgresql-serverを入れる

先ほどの方法でインストールされるのは、実はPostgreSQLのクライアントだけで、サーバはインストールされない。yumでインストールする。

sudo yum install postgresql-server postgresql-contrib postgresql-devel

initdbする

initdbしようとすると、$PGDATAがないと言われてしまった。ググると、postgresql-setupコマンドというのがあることを見つけた。initdbじゃないのか???

sudo postgresql-setup --initdb

これで確かにinitdbはできたのだが、localeの指定やencodingの指定が上手くいかない。環境変数PGSETUP_INITDB_OPTIONSを使えというメッセージも出てたので、設定してみたのだが、なんかうまくいかず…。

再度ググると、postgresユーザになってからinitdbするのがよさげという情報を得た。ユーザpostgresでログインすると、$PGDATAが設定されるのでそちらのほうが良さそう。勉強用の環境のため、接続はtrustのままでいいので-Aオプションは付けなかった。

[ec2-user@postgres ~]$ sudo su - postgres
Last login: Fri Aug  7 18:33:11 UTC 2020 on pts/0
-bash-4.2$ initdb --locale=C --encoding=UTF8
The files belonging to this database system will be owned by user "postgres".
This user must also own the server process.

The database cluster will be initialized with locale "C".
The default text search configuration will be set to "english".

Data page checksums are disabled.

creating directory /var/lib/pgsql/data ... ok
creating subdirectories ... ok
selecting default max_connections ... 100
selecting default shared_buffers ... 128MB
selecting default timezone ... UTC
selecting dynamic shared memory implementation ... posix
creating configuration files ... ok
running bootstrap script ... ok
performing post-bootstrap initialization ... ok
syncing data to disk ... ok

WARNING: enabling "trust" authentication for local connections
You can change this by editing pg_hba.conf or using the option -A, or
--auth-local and --auth-host, the next time you run initdb.

Success. You can now start the database server using:

    pg_ctl -D /var/lib/pgsql/data -l logfile start
-bash-4.2$ exit
logout

起動させる

systemdを使って起動させる。

sudo systemctl start postgresql

接続する

試しに接続してみる。

[ec2-user@postgres ~]$ psql -U postgres
psql (11.5)
Type "help" for help.

postgres=# \q

接続できたのでここまでとする。

後輩との1on1で話したことをまとめておく

1on1というか、今後どうしていきたいか等を話し合っている。継続的に話し合っていくので、まぁ1on1になっていくのかなとも思う。

「一人前」を定義する

目標がめちゃくちゃザックリとしていて、「一人前になる」というものなので、まずは一人前の定義を二人で行った。彼の考える一人前を聞き出して、「つまりはこういうことだろうか?」という感じで固めていった。詰まったときには、「Aさんはあなたから見て一人前と思えますか?」と聞き、そこから、どういうところが一人前と思えるのかを聞き出したりしていった。

現状を振り返る

大体一人前の定義が固まったところで、現状を振り返った。地図があっても現在地が分からなければ、その場所には向かえない。

本格的にプロダクトの開発に入ってもらったことはまだないので、知識も経験もまだまだであることはわかるが、まぁそれは当然のことなので、別に落ち込むことではない。

果たしてそれは本当にやりたいことか?

最近はサイトの作成をやってもらっていて、ようやくそれなりに書けるようになってきたので、それは楽しいという話をしていた。なので、フロントエンドに興味があるという話になったのだが、果たしてそれは本当にやりたいことだろうか?他のことをあまり勉強していない状態で、そう言い切っていいものか?という話をした。先日ホットエントリー入りしていた記事を見せて、説明した。

shiro-16.hatenablog.com

また、越境した結果その分野が実はその人が一番楽しいと思える分野かもしれないからです。僕自身はサーバサイド/インフラから始まり一通り終えてサーバサイド/インフラがやっぱり楽しいと感じましたが、どこかでサーバサイド/インフラより面白いと感じるものがあったのならそこに留まっていたと思うし、仕事をするなら楽しいと思える事をやりたいじゃないですか。経験年数が浅い人ほどというのをつけたのは歳を取ると越境する体力みたいなのが徐々になくなってくるのかなぁと思うからです(個人の感想)

この記事についていたコメントのこれも引用して話した。

ledsunさん: 現実の問題は領域の間に落ちている(それ以外は既に解決されている)ので越境したエンジニアは強い。狭い領域で尖っているエンジニアはわかりやすく強い(実際強い)。

Railsがなんとなく書けるだけでは足りない。コードレビューできるようになるには、Rubyらしい書き方や、RESTの理解が必要だし、自信を持ってそれを言えるだけのバックボーンがいる。自信がないと、「動いているからヨシ!」になってしまってレビューできない。データベースの特性やSQL、インデックスのこと等もわかっていないと、ActiveRecordで作ったクエリが遅くても「なんで遅いのかよくわからんけど動いてるからヨシ!」になってしまう。

遅いのは画像やJS,CSSのファイルサイズが最適化されていなかったからとか、読込が非同期になってなかったからとか、もしかしたらそういうことかもしれない。そういうのは一通り色んな領域を経験しないと気づけない。

ふんわりと要望を伝える

まずは色々やってほしくて、その上でやりたいことを考えていこうということにした。

  • T型人材を目指してほしいこと
  • T型人材になるにしても、浅く広くをできるようになるには、アーキテクチャの知識、エンジニアとしての思想、技術のベースとなる考え方を吸収しておかなければならないこと
  • Railsやフロントエンドは業務でやるからある程度は自動的に力がついていくはず
  • 一人前になるためには、Rails + αのαを頑張ろう
  • αは、Web全般の知識、運用の知識、脆弱性対策方法、アルゴリズムや設計手法、他の言語などなど…

じゃあαをどうやっていくか?っていうところが、おススメの本を聞いて、読んで、感想をアウトプットするとか、得た知識を業務に使っていくという話をした。 とはいえ、自分自身としても「最終的にはもっと本を読もう」で終わってしまうのがなんかモヤモヤしていて、もっといい方法やアイデアないもんか?と思いながら話を終えた。

終えたけれど、「車の免許は座学だけでテストで100点とっても免許渡せないでしょ?実際に運転して運転技術も身につけないといけない」という、いい感じの例えを使えたので、そこはわかってもらえてアウトプットする気になってもらえたみたいでよかった。

Rails 5.2.3から5.2.4.3に更新したらActiveStorageでエラー発生した

社内のRailsアプリのバージョンアップを行ってテストを実行したところ、システムテストが通らなくなりました。

ArgumentError: unexpected value at params[:whitelist_headers]

というエラーが出たので、ググったところ、RailsにPRが…。

github.com

これはRails6.0系の話なので、5.2系はどうなるんだ?と思っていたら、関連issueがありました。

github.com

コメントに、

You can fix this in your own app by upgrading the aws-sdk-s3 gem to 1.48.0 or greater.

とありました。

Gemfile.lockを確認したところ、aws-sdk-s3のバージョンが1.43.0だったので、早速更新。

gem 'aws-sdk-s3', '>= 1.48.0'

これで、bundle update aws-sdk-s3を実行後、テストを実行したら、問題なく通りました!😊

余談

railsのアップグレードをしたら、yarnでrails関連のjsライブラリのバージョンアップもしておきましょう。

yarn add activestorage rails-ujs turbolinks

zshでpecoを使って色々

fishからzshに移行したのですが、便利に使っていた関数を移植し忘れていたのでzsh版を作ってgistで公開しておきます。

zsh functions