Ruby on JetsとRDS Proxyを使ってRailsアプリをサーバレス化してみた

9ec05c5a1b9b0ce9cd53ec3a63838b9a?s=47 Y_uuu
January 09, 2020

Ruby on JetsとRDS Proxyを使ってRailsアプリをサーバレス化してみた

2019/01/09(Thu) 20:20-20:35
AWS re:Invent Recap with Serverless in Fusic にて発表

9ec05c5a1b9b0ce9cd53ec3a63838b9a?s=128

Y_uuu

January 09, 2020
Tweet

Transcript

  1. Ruby on JetsとRDS Proxyを使って Railsアプリをサーバレス化してみた 2019/01/09 20:20-20:35 AWS re:Invent Recap

    with Serverless in Fusic 株式会社Fusic 岡嵜雄平 
  2. ࣗݾ঺հ 岡嵜 雄平(@Y_uuu) 弊社サービスmockmockに携わるエンジニア re:Invent 2019に参加してきました 普段はRailsでの開発が主  ࣗݾ঺հ

  3. ࠷ۙڵຯ͕͋Δ͜ͱ 

  4. ࠷ۙڵຯ͕͋Δ͜ͱ • ࣾ಺χίΧϨγεςϜ /JDPMF 

  5. ࠷ۙڵຯ͕͋Δ͜ͱ • 3VCZPO+FUT 

  6. ࠷ۙڵຯ͕͋Δ͜ͱ • 3%41SPYZ 

  7. ͭΛผʑʹ΍Δͱ͕͔͔࣌ؒΔ ˣ ͭಉ࣌ʹ΍Ε͹͍͍Μ͡ΌͶʁ 

  8. ΍ͬͯΈ·ͨ͠ 

  9. ࠓ೔࿩͢͜ͱ  3BJMTͰ࡞ͬͨΞϓϦΛ+FUT্Ͱಈ͔͢  3%41SPYZΛ࢖ͬͯΈͨ  ·ͱΊ 

  10. 3BJMTͰ࡞ͬͨΞϓϦΛ+FUT্Ͱಈ͔͢ 

  11. 3VCZPO+FUTͱ͸  AWS上で動作するサーバレスアプリケーションを Rubyで書くためのフレームワーク

  12. 3VCZPO+FUTͱ͸  • ORMがRailsと同じActiveRecord • MVCやルーティングの書き⽅(メソッド)が同じ • ⼀部のGemが使える Ruby on

    Railsと同じように実装できる
  13. 3VCZPO+FUTͱ͸  1コマンドでAWSへデプロイできる

  14. 3VCZPO+FUTͱ͸  1コマンドでAWSへデプロイできる DBにRDS・ DynamoDBの 両⽅が使える

  15. LambdaとRDSは相性が良くない  2019年9⽉までの状況 1. VPCに配置したLambdaの起動に時間がかかる 2. Lambdaスケールアウト時にENIが枯渇する懸念 3. RDSへのコネクション数が上限に達する懸念

  16. LambdaとRDSは相性が良くない  2019年9⽉以降ボトルネックが解消されつつある 1. VPCに配置したLambdaの起動に時間がかかる 9⽉のアップデートで解消 2. Lambdaスケールアウト時にENIが枯渇する懸念 9⽉のアップデートで解消 3.

    RDSへのコネクション数が上限に達する懸念 re:Invent 2019でRDS-Proxyが発表
  17. RDBを選択するメリット  • ActiveRecordに依存するGemが使えるかもしれない • データの並び替えや検索が楽 • Railsと同じ感覚で⾼速に実装できる • 既存のRDBからのデータの移⾏が楽

  18. ࠓճ͸3%#Λબ୒ 

  19. 構成 

  20. 構成 

  21. 4FSWFSMFTT 

  22. 3VCZPO+FUTͰͷ࣮૷  アプリケーションを作成する HFNJOTUBMMKFUT KFUTOFXOJDPMFTFSWFSMFTT ˞OJDPMFTFSWFSMFTTσΟϨΫτϦʹ֤छϑΝΠϧ͕ࣗಈੜ੒͞ΕΔ DEOJDPMFTFSWFSMFTT CVOEMFJOTUBMM ZBSOJOTUBMM

  23. 3VCZPO+FUTͰͷ࣮૷  サーバ起動 KFUTTFSWFS ブラウザでアクセス可能

  24. 3VCZPO+FUTͰͷ࣮૷  Scaffoldする KFUTTDBGGPMEVTFSOBNFTUSJOH FNBJMTUSJOH ʜ KFUTECDSFBUF ECNJHSBUF

  25. ΄΅3BJMTͱಉ͡ 

  26. 3VCZPO+FUTͰͷ࣮૷  Railsで作ったNicoleのソースコードを移植

  27. 3VCZPO+FUTͰͷ࣮૷  Railsで作ったNicoleのソースコードを移植

  28. 3VCZPO+FUTͰͷ࣮૷  Railsで作ったNicoleのソースコードを移植

  29. 3VCZPO+FUTͰͷ࣮૷  デプロイする +&54@&/7QSPEVDUJPOKFUTEFQMPZ

  30. ΄΅3BJMTͱಉ͡ 

  31. σϞ  https://5mgq0llbxc.execute-api.ap-northeast-1.amazonaws.com/prod/

  32. Jetsでハマったこと  • RailsにあってJetsにない機能がいくつかある • asset pipeline(CSS/JSはwebpacker、imagesはpublic配下) • flash •

    署名付きcookie • ActiveStorage • simple_format • i18n • (他にもまだありそう)
  33. Jetsでハマったこと  • リンクの⽣成について挙動の違いあり • Rails同様xxx_pathとかxxx_urlでリンク⽣成できる • Helperが⽣成されないケース(resourcesのネストやgetなど) • クエリパラメータ未対応(search/paginationに難あり)

  34. Jetsでハマったこと  • デプロイ環境で問題が発⽣した際の調査 • CloudWatch Logs頼みなので原因の切り分けが難しい • Lambdaの数が膨⼤なのでログ解析が困難 •

    ログ解析基盤が無いと詰むかも
  35. 意外と⼤丈夫だったこと  • 簡単にデプロイできる • IAMの設定 • Lambdaのサブネット、セキュリティグループの設定 • 他はデフォルトのまま

  36. 意外と⼤丈夫だったこと  • 想像以上にRailsから移植しやすい • ModelとControllerはほぼコピペでOK • Viewのみリンク周りの修正が必要

  37. ϋϚͬͨ఺͸1VMM3FRVFTUͷνϟϯε ͩͱࢥͬͯ෇͖߹͍͖͍ͬͯͨ 

  38. 余談︓Rails Support  • 既存のRailsアプリをjets deployできる https://rubyonjets.com/docs/rails/afterburner/ • これを使えばもっと簡単にサーバレス化できたかも…

  39. 3%41SPYZΛ࢖ͬͯΈͨ 

  40. おさらい︓現状の構成 

  41. 現状の構成でのスケールアウト  Heyで100リクエストしてみる ❯ hey -H "Cookie: rack.session=xxx" -n 100

    -c 100 https://5mgq0llbxc.execute-api.ap-northeast-1.amazonaws.com/prod/ ※省略 Status code distribution: [200] 66 responses [502] 34 responses
  42. 現状の構成でのスケールアウト  db.t2.microのMAXコネクションで頭打ちに

  43. AuroraServerlessを使った構成 

  44. 4FSWFSMFTT 

  45. AuroraServerless構成でのスケールアウト  Heyで1024リクエストしてみる ❯ hey -H "Cookie: rack.session=xxx" -n 1024

    -c 1024 https://5mgq0llbxc.execute-api.ap-northeast-1.amazonaws.com/prod/ ※省略 Status code distribution: [200] 1024 responses
  46. AuroraServerless構成でのスケールアウト  コネクション数に応じてスケールアウト

  47. RDS-Proxyを使った構成  ※RDS Proxyの最⼤接続数は80%(66×0.8=52)としています

  48. 4FSWFSMFTT 

  49. RDS-Proxyを使った構成  Heyで50リクエストしてみる ❯ hey -H "Cookie: rack.session=xxx" -n 50

    -c 50 https://5mgq0llbxc.execute-api.ap-northeast-1.amazonaws.com/prod/ ※省略 Status code distribution: [200] 24 responses Error distribution: [26] Get https://5mgq0llbxc.execute-api.ap-northeast- 1.amazonaws.com/prod/: net/http: request canceled (Client.Timeout exceeded while awaiting headers)
  50. RDS-Proxyを使った構成  Heyで50リクエストしてみる(タイムアウトを120秒に延ばす) ❯ hey -H "Cookie: rack.session=xxx" -n 50

    -c 50 –t 120 https://5mgq0llbxc.execute-api.ap-northeast-1.amazonaws.com/prod/ ※省略 Status code distribution: [200] 24 responses [504] 26 responses 29秒で⼀⻫に504が返ってくる= API Gatewayのタイムアウト
  51. RDS-Proxyを使った構成  原因は調査中 • ブラウザでアクセスすると特に異常はない RDS Proxy経由で⼤量のアクセスしたときに 要求を捌ききれていない︖ • エンドポイントをRDSに戻すと特に異常はない

  52. RDS-Proxyを使った構成  原因は調査中 • RDS-Proxyを経由するとRDS側のコネクション数が 40を超えない

  53. RDS-Proxyを使った構成  原因は調査中 • RDS(MySQL)のmax_connectionsは66

  54. RDS-Proxyを使った構成  原因は調査中 • DatabaseConnectionsCurrentlySessionPinnedが発⽣ • 接続の再利⽤効率の低下を引き起こす可能性があるとのこと 参考︓Managing Connections with

    Amazon RDS Proxy (Preview) https://docs.aws.amazon.com/AmazonRDS/latest/AuroraUserGuide/rds-proxy.html
  55. RDS-Proxyを使った構成  原因は調査中 • PinningとRDSのコネクション数が増えない現象の 因果関係は確認中 • Pinningの回避策は模索中

  56. RDS-Proxyを使った構成  原因は調査中 • AWSサポートとのやり取り継続中です • 原因が特定できたら何らかの⽅法で共有します

  57. ·ͱΊ 

  58. まとめ  • Ruby on Jetsを使ってRailsアプリケーションを サーバレス化することができた • Aurora Serverlessを使ってLambdaの

    スケールアウト対策ができることがわかった • RDS-Proxyについては引き続き検証を続ける
  59. Thank you! Fusicは技術が好きなエンジニアを 募集しています