Tech Racho エンジニアの「?」を「!」に。
  • Ruby / Rails関連

週刊Railsウォッチ(20210601後編)Python使いから見たRuby、MySQLのインデックス解説、GitHubが採用したOpenTelemetryほか

こんにちは、hachi8833です。

週刊Railsウォッチについて

  • 各記事冒頭には🔗でパーマリンクを置いてあります: 社内やTwitterでの議論などにどうぞ
  • 「つっつきボイス」はRailsウォッチ公開前ドラフトを(鍋のように)社内有志でつっついたときの会話の再構成です👄
  • お気づきの点がありましたら@hachi8833までメンションをいただければ確認・対応いたします🙇

TechRachoではRubyやRailsなどの最新情報記事を平日に公開しています。TechRacho記事をいち早くお読みになりたい方はTwitterにて@techrachoのフォローをお願いします。また、タグやカテゴリごとにRSSフィードを購読することもできます(例:週刊Railsウォッチタグ)

🔗Ruby

🔗 書籍『Webで使えるmrubyシステムプログラミング入門』


つっつきボイス:「前回の銀座Rails#33でこの本の著者がmrubyのプレゼン↓をやってたのを見て、面白そうな本なのでその場で注文かけました」「私もこの本買ってました(読まなきゃ😅)」

🔗 Python使いから見たRuby


つっつきボイス:「これはいい記事でしたね」「私も楽しく読みました」

「この記事ではPythonですが、他の言語(PHP、Java、JavaScriptなど)をやっている人もこの記事で解説されていることを押さえておけば "ある程度まで" Rubyを読めるようになれるでしょうね」

「見方を変えると、他の言語を知っている人が予備知識なしでRubyのコードを読もうとすると、なかなかフィーリングだけでは読めないということでもあると思います」「言われてみるとRubyの構文は少し独特かも」「たとえばJavaをやっている人なら、JavaScriptやPythonを初めて読むときにもある程度までフィーリングで読めると思うんですけど、そういう人がいきなりRubyを読むと、まずeachの読み方がわからなかったりするんですよ」「あ、そうかも」「わかる気がします」

「Rubyには他にもシンボルの概念や%記号、変数名や関数名は小文字で始めてクラス名は大文字で始めるといった縛りなど、他の言語にないものも多いんですよ」「Rubyの例外処理にbeginがなくて、rescueensureのインデントが飛び出ている↓のも、Javaから入った自分は最初戸惑いました」「Rubyを使っているとそれが普通なんですけどね」

# 同記事より
def hoge
  p "main process"
  raise "just for test"
rescue => e
  p "error occurred: #{e.message}"
ensure
  p "this line is always called"
end

「この記事はそういう他の言語から来る人たちにとって役立つと思います👍」「ボリュームがそんなに多くないのもありがたいですね」

🔗 Cの側からRubyを覗く(Ruby Weeklyより)


つっつきボイス:「こちらはCRubyを記述するC言語の側からRubyを覗くという企画のシリーズ記事だそうです」「CRubyの内部実装を解説する記事ですね」「第3回はメソッド呼び出しや可変長引数、キーワード引数、ブロック付きメソッド呼び出しが解説されてる」「最後に練習問題も付いてますね」「CRubyのコードを追う機会は普段なかなかないな〜」

🔗 hashdiff: ハッシュ同士を比較するgem

liufengyun/hashdiff - GitHub


つっつきボイス:「ハッシュのdiff?」「あ〜、こういうふうに差分を配列で取り出せるのか↓」「+-が追加と削除で、~が変更かな」「GitHubとかのdiff viewの感覚で差分を出せる感じ」「巨大なarrayの比較には使わないでくれと書かれてました」

# 同リポジトリより
a = {a:{x:2, y:3, z:4}, b:{x:3, z:45}}
b = {a:{y:3}, b:{y:3, z:30}}

diff = Hashdiff.diff(a, b)
diff.should == [['-', 'a.x', 2], ['-', 'a.z', 4], ['-', 'b.x', 3], ['~', 'b.z', 45, 30], ['+', 'b.y', 3]]

「ところで、こういうdiff viewの挙動ってどこでもだいたい同じだけど、共通のdiffライブラリがあるのかな?🤔」「ググってみるとGoogleのdiff-match-patchというライブラリが出てきた↓」「C++、C#、Python、Objective-C、JavaScriptなどいろんな言語に対応してるんですね」「Rubyはないのか〜」「Luaはあるのに」

google/diff-match-patch - GitHub

🔗 その他Ruby

# 同PRより
$ irb
irb(main)[01:0]> ls ERB.new('test')
ERB#methods:
  def_class         def_method        def_module        encoding          filename          filename=         lineno
  lineno=           location=         make_compiler     result            result_with_hash  run               set_eoutvar
  src
instance variables: @_init  @encoding  @filename  @frozen_string  @lineno  @src

つっつきボイス:「小ネタですけど、RubyのIRBにpryと同じようなlsコマンドが入っていたそうです」「k0kubunさんのお仕事」「最近のIRBの使い勝手、本当によくなったと思います」「自分もpryをすっかり使わなくなりましたね」「私も」「本体にbundleされたライブラリの機能が向上するのはいい👍」


「ついに教科書進出!」「よく見たら地理の教科書でした」「Rubyって地域の特産物なのかしら?」「焼き物とか漆器みたいな趣」

🔗DB

🔗 スライド『MySQLとインデックスと私』


つっつきボイス:「そうそう、このスライドはよかった: 令和時代のMySQLインデックスのお話」

「インデックスを図示する方法がうまい↓」「たしかに見やすいですね」「実際のMySQL内部のデータ構造がこうなっているというわけではないと思いますが、RDBMSが与えられたクエリからデータを検索していく順番がうまく図示されているのがとても良いと思います👍」「なるほど」「データがフィルタされる過程はだいたいこのスライドのとおりです」

「複合インデックスのしくみやインデックスマージの話などいろいろ解説されていますね」「結局このあたりは自力でデータベースをチューニングするようにならないとなかなか身につかないんですよ」「データベースとみっちりお付き合いしないとだめか...」

「入っているデータによってクエリプランが変わるというのも割と大事なポイントですね」「はい」「これはPostgreSQLの話ですが、以前stagingではmerge joinしてるのにproductionではフルスキャンする、みたいなケースがありました: 原因は恐らくproductionのレコード数が多すぎて、merge joinするためのメモリ容量が足りなくなったんじゃないかと結論づけました」「お〜」「こういうのを追いかけるにはRDBMS自体の知識がそれなりに必要ですね」

🔗 RDB内の実行順序

「RDBを学ぶときは、RDBの中でどのような順序で処理が進められるかという流れが大事で、これを最初に理解しておかないと今のインデックスの話などもなかなかしっくりこないと思います」「なるほど」「これまでも引き合いに出した(ウォッチ20190416)、そーだいさんの『失敗から学ぶRDBの正しい歩き方』にもそうした知見が豊富にあります↓」「そうそう、これ買いました」「買いました〜」

「同書は現場で実際によくある事例がたくさん紹介されていてとてもよい本です👍」「この本すごくわかりやすかった」「特に同書の『6.2 リレーショナルモデルとソートのしくみ』図6.1『RDBMSとエクゼキュータ』はとても大事: この実行順序を理解しておかないと、最適化するポイントを間違えてしまったりして最適化の意味がなくなる」「この図大事ですね」「この図を理解するためだけにこの本を買ってもいいぐらい」

Julian Evansさんの以下の記事に、同書よりもう少し簡単な図が掲載されています↓。

参考: SQL queries don't start with SELECT

「今回取り上げたスライドも、そーだいさんのツイートで知ったと思います」

つっつきの後で探してみました↓。

🔗 Active RecordとRDB

「ところでActive RecordのメソッドチェーンもRDBの実行順序を意識しないといけないんでしょうか?」「SQLの最終的な実行順序はRDBの中の話なので、Active Recordのメソッドチェーンの順序は基本的に影響しません」「なるほど!」

「その代わりActive Recordのメソッドには、典型的なデータと典型的なクエリの場合にはクエリをこう書き換えると速くなるといったクエリ効率化のノウハウがいろいろ盛り込まれているので、 単純かつ頻繁に使われるようなユースケースであれば、RDBのことを気にしなくてもある程度速度を出せます」「お〜」「クエリが複雑になって典型的なパターンでなくなってくる場合には、to_sqlで取り出した生SQLのクエリプランを確認したり、想定しているインデックスが使われてるかなどを確認して最適化する必要があるでしょう」

「あとActive Recordのscopeが複雑になってくると、これなら速いだろうと思っていた処理が実際にはやたら遅くて、よく調べたらscopeの中で複雑な条件を付けていてそれが遅かった、みたいなことはあります」「そうそう」「実際の業務アプリでは典型から外れることもよくありますね」

🔗クラウド/コンテナ/インフラ/Serverless

🔗 App Runner続報


つっつきボイス:「先週(ウォッチ20210525)に続いてAWS App Runnerの話題です」

「記事を見てみると、サービス設定にいろいろ制約があるみたい」「大規模なアプリケーションは対象にしてない感じでしょうか?」「たぶんサービスが立ち上がって間もないだけでしょうね」「それもそうか」「AWS Lambdaも初期は数秒程度のexecution timeしか許されていなかったので、それと同じように最初は大規模にしないだろうと思います」

「KMSは使える」「AWS Copilotは使ったことなかった」「Copilotは今使ってて、ちょっとGoogle App Engineに似た雰囲気を感じました」「Systems Manager パラメータストアが使えないのはちょっとしんどそうだけど、必要とされる機能だし、このあたりは今後連携できるようになっていくんじゃないかなという気がする」「そうなって欲しいですね」

参考: AWS Key Management Service(マネージド型の暗号化キー作成と管理)| AWS
参考: AWS Copilot のご紹介 | Amazon Web Services ブログ
参考: AWS Systems Manager パラメータストア - AWS Systems Manager

「早くもApp RunnerでRailsを動かすスクリーンキャストが公開されてました↓」「今のAWSでRailsを動かすのはなかなか大変なので、App Runnerでもっと楽にやれるといいでしょうね」

🔗 GitHubがOpenTelemetryを採用(Hacklinesより)


つっつきボイス:「OpenTelemetryとは?」「下の日本語記事によると、OpenCensusOpenTracingというオープンなサービス監視標準が最近統合されてOpenTelemetryができたそうです」「お、どこかで見たと思ったら、銀座Rails#24で発表されてたのをこの図↓で思い出した」「お〜」


同記事より

参考: OpenTelemetry とは  |  Google Cloud
参考: OpenTelemetry: 計装器を長く使い続けるために - New Relic公式ブログ
参考: OpenCensus(OpenTelemetry)とは | フューチャー技術ブログ

「現代のサービスはユーザーからリクエストを受けてレスポンスを返すまでにたくさんのサービスを経由しますよね: たとえばAWS API Gatewayを通り、Lambdaを呼んで、LambdaがRDBにアクセスし、RDBはSQLを発行するとか」「ですね」「そうしたすべてのサービスがモニタリング用の共通のリクエストIDを共有して、各処理内での所要時間などを付与するフォーマットが標準化されていることで、異なるサービス群を複数使っていてもトレーシングを共通化できるというメリットがあります」「ふむふむ」「そのための規格がいくつかあって、OpenTelemetryはそのひとつだと理解しました」「お〜、そういうのがあったとは」

「この記事に載っているRailsのInstrumentation機能↓は、Railsのあらゆるステータスログを出力できるんですけど、これをOpenTelemetryに対応させられれば、OpenTelemetryをサポートするあらゆる監視サービス(DataDogとか)やビジュアライズツールを使えるようになります」「それでNewRelicも上の日本語記事でもOpenTelemetryに協力していると書いていたんですね」

# 同記事より
# in an initializer, or config/application.rb
OpenTelemetry::SDK.configure do |c|
  c.use 'OpenTelemetry::Instrumentation::Rails'
  c.use 'OpenTelemetry::Instrumentation::PG', enable_sql_obfuscation: true
  c.use 'OpenTelemetry::Instrumentation::ActiveJob'
  # This application makes a variety of outbound HTTP calls, with a variety of underlying
  # HTTP client libraries - you may not need this many!
  c.use 'OpenTelemetry::Instrumentation::Faraday'
  c.use 'OpenTelemetry::Instrumentation::Net::HTTP'
  c.use 'OpenTelemetry::Instrumentation::RestClient'
end

参考: Active Support の Instrumentation 機能 - Railsガイド
参考: クラウド時代のサーバー監視&分析サービス | Datadog

「最初の記事に戻ると、GitHubがOpenTelemetryを採用したというのは、どうやらGitHub内部のRailsでOpenTelemetryを利用しているということみたい」「外部サービスかと思ったらユーザーには直接関係なさそう」「GitHubはOpenTelemetryを使いつつOpenTelemetryを支援しているという記事のようですね」

🔗JavaScript

🔗 SICPのJavaScript版

参考: 計算機プログラムの構造と解釈 - Wikipedia


つっつきボイス:「SICPって何だっけと思ったら、紫色の表紙を見て思い出した」「コンピュータサイエンスをScheme言語(LISP言語の方言)で学ぶ有名な教科書でしたね」

「昔大学でScheme動かしながら学んだ覚えがありますけど、ある時期からはPython版も出てますよ」「え、知りませんでした」「米国だと最近の学生はPythonでないとやってられないとか何とか」「オリジナルのSICPはMITから出版されたんだったかな」

参考: Scheme - Wikipedia
参考: Introduction | SICP in Python

「SICP(Structure and Interpretation of Computer Programs)は日本語だと『計算機プログラムの構造と解釈』」「日本語版を出していたピアソンも今はないんだな...」「そのJavaScript版が出たということですね」「JavaScriptでコンピュータサイエンス学びたい人にはよさそう」「いい本だと思いますけど、ゼミで集まってやるならともかく、ひとりで学ぶのは相当つらいんじゃないかな〜」


後編は以上です。

バックナンバー(2021年度第2四半期)

週刊Railsウォッチ(20210531前編)RailsConf 2021の動画が公開、GraphQLのN+1を自動回避、Ruby 3のJITとRailsほか

今週の主なニュースソース

ソースの表記されていない項目は独自ルート(TwitterやはてブやRSSやruby-jp SlackやRedditなど)です。

Ruby Weekly

Hacklines

Hacklines


CONTACT

TechRachoでは、パートナーシップをご検討いただける方からの
ご連絡をお待ちしております。ぜひお気軽にご意見・ご相談ください。