AR ホームベーカリー

オイラのアウトプット用ホームベーカリー!

ActiveRecord Relation の内容をビャッと view に出す

Model.select("created_at").first

とかすると、#<ActiveRecord::reration:〜〜〜> という感じのオブジェクトが頂けるので、いや拙者は値だけがほしい……というときにビャッとする。

Model.pluck("created_at").first

なるほど配列なので select ではなく pluck みたいな気持ちになってしまった。 とりあえず view に「ビャッ!」と出したい時はこれでいいか。

ENV が利用できない(ので ENV を利用できるようにする)

なんのこっちゃい、という感じですが。 だいたいこちらに書いてあるとおりです、ありがてえ。

zenn.dev

Rails環境変数呼び出し

rails new ./example とかして sqlite で初期化すると、こんな感じの config/database.yml が生成されると思います。

default: &default
  adapter: sqlite3
  pool: <%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %>
  timeout: 5000

以下省略

<%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %> の部分は、環境変数 RAILS_MAX_THREADS を参照し、存在しなければ 5 を利用する。 という動作です。 やったー簡単に環境変数を呼べる!

redis で呼ぶ

gem 'redis' を指定した環境にて、上記と同じ様に config/redis.yml から、 ENV環境変数呼べ……ない!

default: &default
  db:
    host: <%= ENV['REDIS_HOST'] %>

REDIS_HOST127.0.0.1 などなんかしらの値が入っていても、実際にコードが読まれると <%= ENV['REDIS_HOST'] %> として解釈され、値が展開されない。

どうする

yaml を理解できないならできるようにしてやればよいのです。 というわけで、実際に <%= ENV['REDIS_HOST'] %> を呼び出している Ruby のファイル先頭に、記述を追加します。

今回は sidekiq+redis という環境だったので、呼び出しているのは config/initializers/sidekiq.rb でした。 こちらの先頭に追加してやります。

yaml = ERB.new(Pathname.new('config/redis.yml').read).result

redis_config =
  if YAML.respond_to?(:unsafe_load)
    YAML.unsafe_load(yaml)[Rails.env] || {}
  else
    YAML.load(yaml)[Rails.env] || {}
  end

# 適当にテスト
print ENV.fetch ('REDIS_HOST') {"aaaaaaaaaaaaaaaaaaaaaaaaadeneeeeeeeaaaaaaaaaaaaaaaaaaa"}

以下省略

ログに、環境変数として指定した値が出ればオッケーです。

ちなみに

本当はこのように、もうちょっと簡単に記述できます。

qiita.com

して unsafe_load load に分けてるナンデ? というと Psych 4.0.0 で破壊的修正がこのあたりに入ったらしく、という話を聞いており。 このへんかな?

www.hsbt.org

幸いにして僕は、このあたりの問題にまだぶつかってないんですが。 じゃあ Railsdatabase.yml を読み込む部分についてはどうなん? と調べたら、場合分けされていたのでパクった、ということですね。

github.com

      def load_database_yaml # :nodoc:
        if path = paths["config/database"].existent.first
          require "rails/application/dummy_erb_compiler"

          yaml = DummyERB.new(Pathname.new(path).read).result

          if YAML.respond_to?(:unsafe_load)
            YAML.unsafe_load(yaml) || {}
          else
            YAML.load(yaml) || {}
          end
        else
          {}
        end
      end

Rails のコード、全体を一斉に読もうとするとなにがなんだか、という感じですが。 こうやって問題にぶちあたって、部分部分だけ拾えると「へえっ!」ってなるので面白い。

というのを 10 年以上前に当時居た会社の CEO に言われてたんですが、めぐりめぐってようやく言葉の意味がわかってきましたね。 Rails なんもわからん。

ElastiCache ことはじめ以前のななめ読みと、それでも作らないといけないときの覚書

とりあえず作らないといかん! という感じの時にななめ読みで助かったやつとか自分のメモ。

パラメータグループの何を最低限設定しておきましょう、とか記事が本当になくて困る。 (RDS で MySQL 選択した場合に例えると character-set を UTF8MB4 とか、 collation の utf8mb4_ja_0900 系とか timezone のそういうやつ )

ElastiCache インスタンスの動作設定について

とりあえずこれだけ設定すれば、フェイルオーバ起きても (エンドポイント参照先切り替わり時に write ロックかかるけど) 最低限大丈夫そう。

  • クラスター無し
    • シャーディング無し
  • レプリカ 1
  • マルチ AZ

nyamadori.hatenablog.com

だいたいこんな理解になった

  • クラスタ:マンション
  • シャード:部屋
    • シャーディング:二部屋契約してぶち抜き利用
  • ノード:住人
  • レプリカ:愚かなレプリカルークゥゥ!

作っておいたほうがいいもの

  • VPC セキュリティグループ
    • ElastiCache に割り当てる用を作ってデフォルトの 6379 か設定するポート番号をふっとくといい
  • サブネットグループ
    • 所属させる VPC 決めた時点で紐付いてるサブネット情報参照できるから、複数の AZ で用意しといて
  • パラメータグループ
    • とりあえず何もいじらず名前だけつけたの作って割り当てればいい、でないと後にチューニングできないんで (RDS の default と同じ問題)

メンテナンスウィンドウ

正直止めたいけど RDS と違って止められないのでロックされる瞬間があるのは諦めるしかない。 時間はもう適当にアクセスなさそうか、あっても「気の所為でしょ!」ってごまかせるタイミングにするしかない。

メール通知するようにしたけど、 SNS トピックに日本語や記号使えなくてキレそう。

dev.classmethod.jp

手動で置換したほうがいいらしい

プライマリノードで書き込みロックかかるし、通知くるんだからまあサービスのメンテナンス入れて対応したほうが確実やんね。

www.slideshare.net

Aamzonlinux2 に Redis-cli を入れる

作成した ElastiCache クラスターのエンドポイントと接続確認をしたい。

epel とか remi 使えって書いてあって「いや嘘だろ」って顔になった。

インストール

[ec2-user@localhost ~]$ sudo amazon-linux-extras install redis6
Installing redis

#snip#

依存性の解決をしています
--> トランザクションの確認を実行しています。
---> パッケージ redis.x86_64 0:6.2.3-1.amzn2 を インストール
--> 依存性解決を終了しました。

依存性を解決しました

==================================================================================================================================================================================
 Package                              アーキテクチャー                      バージョン                                     リポジトリー                                      容量
==================================================================================================================================================================================
インストール中:
 redis                                x86_64                                6.2.3-1.amzn2                                  amzn2extra-redis6                                1.1 M

トランザクションの要約
==================================================================================================================================================================================
インストール  1 パッケージ

総ダウンロード容量: 1.1 M
インストール容量: 3.7 M
Is this ok [y/d/N]: y
Downloading packages:
redis-6.2.3-1.amzn2.x86_64.rpm                                                                                                                             | 1.1 MB  00:00:00
Running transaction check
Running transaction test
Transaction test succeeded
Running transaction
  インストール中          : redis-6.2.3-1.amzn2.x86_64                                                                                                                        1/1
  検証中                  : redis-6.2.3-1.amzn2.x86_64                                                                                                                        1/1

インストール:
  redis.x86_64 0:6.2.3-1.amzn2

完了しました!

動作確認

redis-cli -h ${(プライマリ/リーダー)エンドポイント} -h ${port} ping
PONG

cURL アクセス時にヘッダを表示する

API のテストとか httpd など設定変更して、 curl 実行した時のヘッダを表示する方法。

curl -H "ヘッダ: 値" ${その他必要なら色々オプションつける} --dump-header - http://api.example.com/ 

これで標準出力にシュッと出るので確認できる。