.save

セーブがしたいんです…

t2microにてwordpressを運用していたが、度々mysqlがダウンしていた話

wordpress運用環境

t2microのスペック

 

https://aws.amazon.com/jp/ec2/instance-types 

ダウン現象

 wordpressの記事更新をする際にメモリの使用量が1GBを超える
以下はインスタンスタイプをt2.xlargeにした際に検証を行い、topコマンドでモニタリングしたもの

top - 02:42:42 up 4 days, 16:52,  3 users,  load average: 0.20, 0.13, 0.05
Tasks: 140 total,   2 running,  89 sleeping,   0 stopped,   1 zombie
%Cpu(s):  8.8 us,  0.6 sy,  0.0 ni, 90.4 id,  0.0 wa,  0.0 hi,  0.2 si,  0.0 st
KiB Mem : 16424208 total, 13677544 free,  1198980 used,  1547684 buff/cache
KiB Swap:        0 total,        0 free,        0 used. 14903952 avail Mem

間違った対応

2019-04-18 02:37:52 5604 [Note] InnoDB: Initializing buffer pool, size = 128.0M
InnoDB: mmap(137363456 bytes) failed; errno 12
2019-04-18 02:37:54 5604 [ERROR] InnoDB: Cannot allocate memory for the buffer pool
2019-04-18 02:37:55 5604 [ERROR] Plugin 'InnoDB' init function returned error.
2019-04-18 02:37:55 5604 [ERROR] Plugin 'InnoDB' registration as a STORAGE ENGINE failed.
2019-04-18 02:38:08 5604 [ERROR] Unknown/unsupported storage engine: InnoDB
2019-04-18 02:38:08 5604 [ERROR] Aborting

上記のエラーを見て、innodb_buffer_pool_sizeがデフォルトの128.0Mでは足りないと判断を設定し、これを通常そのようにするらしい、「メモリの8割のサイズを設定する」というものにする

innodb_buffer_pool_size : InnoDBを使っている場合、どんな環境でも一番最初に設定しなければならない値。 バッファプールとは、データとインデックスがキャッシュされる領域だ。 これをできる限り大きくしておくことで、読み出しの処理をディスクからではなくメモリから行うことができるようになる。 一般的な値は、5-6GB(8GB RAMの場合)、20-25GB(32GB RAM)、100-120GB(128GB RAM)。

https://yakst.com/ja/posts/200

ただし、そもそもmysql処理にかかるメモリがインスタンスのメモリサイズをオーバーしていたことが原因だったので、これではmysqlダウンの現象解決にはならない
解決策はメモリを増やすか、swap領域を拡張する必要があったのではないかと考えた

スワップ領域を増やす方向で考える

スワップ領域とは

スワップ領域とは 使っていないメモリの内容を一時的にしまっておくための場所 です。

https://wa3.i-3-i.info/word1721.html

つまり、「メモリが足りないならHDに保存すればいいじゃない!」という話
ちなみにインスタンスのストレージは「EBS のみ」となっている

EBSとは

Amazon Elastic Block Store (Amazon EBS) は、AWS クラウド内で Amazon EC2 インスタンスと組み合わせて使用できる、永続的なブロックストレージボリュームです。コンポーネントに障害が発生した場合でも高い可用性と耐久性を提供できるように、各 Amazon EBS ボリュームはアベイラビリティーゾーン内で自動的にレプリケートされます。Amazon EBS ボリュームは、作業負荷の実行に必要な安定した低レイテンシーのパフォーマンスを提供します。Amazon EBS を使用すると、使用量の拡張または縮小を分単位で行うことができます。プロビジョニングしているサイズに合わせて、低料金でご利用いただけます。

https://aws.amazon.com/jp/ebs/

気になるお値段(というか課金体系)

EBS 汎用 SSD (gp2) ボリューム 汎用 SSD (gp2) ボリュームのボリュームストレージの料金はプロビジョニングした容量 (GB/月) で決まり、お客様がそのストレージを解放するまで毎月料金が発生します。gp2 ボリュームのプロビジョニング済みストレージは、1 秒ごとに課金されます (最小課金時間は 60 秒)。I/O はボリュームの料金に含まれているため、プロビジョニングした各ストレージの GB に対してのみ課金されます。

*プロビジョビングとは

プロビジョニングとは、必要に応じてネットワークやコンピューターの設備などのリソースを提供できるよう予測し、準備しておくことです。供給や設備等の意味を表すプロビジョン(provision)という単語がもととなって派生した言葉です。

つまり使った分だけお値段が発生するってこと

今回の運用ではメモリのオーバー幅は500MBくらいなので、EBSにスワップ領域を確保してもそんなにお金はかからないと判断

念のためのシミュレーション結果

プロビジョニングされたストレージ 1 GB の月額料金が 0.12USD

https://aws.amazon.com/jp/ebs/pricing/?nc=sn&loc=3

だいたい0.06USD/月か オーライ

本当に落ちないのか検証する

今回のダウン騒動で、問題のインスタンスはサイズアップをしてしまったので検証はできず。。
なので個人でAWSwordpress使って技術ブログでも運用してみるとする

erb2slimを実行時にno implicit conversionエラーが出る

やりたいこと

 index.html.erbをslimに変換したい。

 

gem

 gem 'slim-rails'

 gem 'html2slim'

 

コマンド

 erb2slim

 

エラー文

 TypeError: no implicit conversion of IO into String

   Use --trace for backtrace.

 

IOを文字列に変換することはできない、という意味のエラーだと理解。

 

--traceを実行

 /Users/ほげほげ/.rbenv/versions/2.3.1/lib/ruby/gems/2.3.0/gems/html2slim-0.2.0/lib/html2slim/converter.rb:17:in `open': no implicit conversion of IO into String (TypeError)

 

 converter.rbのファイルを開こうとしてエラー?

 ファイルの中まで掘ってる時間がないので、一旦ここまで。もう手動で換える。

 でもくやしいので、詳しい方教えてください!

 

ruby silver 勉強記録 (6日目)

・日付

%Y :4桁の西暦

%y:2桁の西暦

%m:月

%d:日

%H:時刻

%M:分

%S:秒

 

・ハッシュ

インスタンスメソッド

clear : ハッシュを空にする。

fetch : キーに対応する値を取り出し、キーがなければ指定の値を返す。

invert : キーを値に、値をキーにする。

 

・%、%s

%: ダブルクオートで囲う場合と同等。シングルクオートやダブルクオートのエスケープが不要になる。後述の%q()と違い、変数・定数の展開もできる。

str = %(Programming language "Ruby")
puts str
# => Programming language "Ruby"

 

%s: シンボルにする。式の展開はされない。

sym = %s(Ruby)
p sym
# => :Ruby

 

qiita.com

 

 

・contact

 concatメソッドは、配列arrayの末尾に引数の配列other_arrayを結合します。

fruits = ["apple", "orange", "banana"]
fruits.concat(["kiwi", "strawberry"])
p fruits
["apple", "orange", "banana", "kiwi", "strawberry"]

concat (Array) - Rubyリファレンス

 

・chop

 

str.chop

chopメソッドは、文字列の末尾から1文字を取り除いた新しい文字列を返します。末尾が"\r\n"で終わっている場合だけは、"\r\n"の2文字を取り除きます。

s = "hello"
puts s.chop
hell

 

・ヒアドキュメントとは

Ruby

Rubyにもヒアドキュメントが存在し、それは <<識別子 を含む行の次の行から識別子だけの行の直前までを文字列とする行指向のリテラルである[6]。例えば、

print <<EOS      # 識別子 EOS までがリテラルになる
  the string
  next line
EOS

のように書くと、以下と同じように出力される。

print "  the string\n  next line\n"

ヒアドキュメント - Wikipedia

 

・モジュールとは

まずモジュールとは何かについて見ておきましょう。モジュールは次のようなものです。

module モジュール名

end

モジュールは「module」から始まり「end」で終わりとなります。そしてモジュールにはモジュール名を指定します。

クラスの中でモジュールを利用できるようにするにはクラスの中に次のように記述します。

include モジュール名

インクルードされたモジュールはクラス内のインスタンスメソッドと同じように実行する事が出来ます。

www.rubylife.jp

 

 

20170608 ruby メモ

obj.is_a?(klass)
obj.kind_of?(klass)

is_a?メソッドまたはkind_of?メソッドは、レシーバのオブジェクトが引数klassクラスのインスタンスであればtrue、そうでなければfalseを返します。

instance_of?メソッドとは違い、レシーバが属するクラスだけでなく、レシーバが属するクラスの親クラスやインクルードしているモジュールをklassに指定してもtrueが返ります。

次の例では、配列arrArrayクラスのインスタンスですが、ArrayクラスはObjectを親クラスとし、Enumerableモジュールをインクルードしているので、ArrayObjectEnumerableのどれをkind_of?に渡してもtrueになります。

arr = [1, 2, 3]
puts arr.kind_of?(Hash)
puts arr.kind_of?(Array)
puts arr.kind_of?(Object)
puts arr.kind_of?(Enumerable)
false
true
true
true

 

Rubyスクリプトで目にする以下のイディオムは、左辺が未定義または偽なら右辺の値を代入するという意味だ。このイディオムは変数の初期化で良く用いられる。

a ||= true

Rubyの||=というイディオムは左辺が未定義または偽なら代入の意味 -- ぺけみさお

 

sym.to_sym

to_symメソッドは、レシーバのシンボル自身を返します。

sym = :message
p sym.to_sym
:message

 

ref.xaio.jp

 

build

newメソッドのAlias
モデルオブジェクトを生成する。
保存はまだされていないため、saveメソッドなどを使って保存する。
生成と同時に保存したい場合は、createメソッドを使用する。

使い方

モデル.build([属性])

引数なし
person.pets.build
# => #<Pet id: nil, name: nil, person_id: 1>

build - リファレンス - - Railsドキュメント

 

pluck

任意のカラムの配列を取得(pluck)

説明

任意のカラムの配列を取得する

使い方

モデル.pluck(カラム名)

Person.pluck(:id)
# SELECT people.id FROM people
# => [1, 2, 3]

 

 

 

 

 

ruby silver 勉強記録 (7日目)

・?A

 「?」に一文字足すと、その文字自身を一文字だけ含む文字列オブジェクトを返す。

 p ?A

# => "A"

 

・配列

位置と数

array[index, length]

引数に整数2つ(indexlength)を指定したときは、indexの位置からlength個の要素を取り出して、配列で返します。indexが範囲外のときはnilを返します。また、indexが要素の数と同じときは空の配列を返します。

引数indexにマイナスの値を指定したときは、配列の末尾から数えます(-1が後ろから1番目、-2が後ろから2番目、...)。

animals = ["dog", "cat", "mouse", "rabbit", "horse"]
p animals[1, 3]   # 2番目から3個
p animals[-3, 2]  # 末尾から3番目から2個
p animals[5, 3]   # index == 要素数
["cat", "mouse", "rabbit"]
["mouse", "rabbit"]
[]

範囲

array[range]

引数に範囲rangeを指定すると、その範囲の位置から要素を取り出して、配列で返します。rangeが配列の範囲外のときはnilを返します。また、rangeの開始位置が要素の数と同じときは空の配列を返します。

rangeにマイナスの値を指定したときは、配列の末尾から数えます(-1が後ろから1番目、-2が後ろから2番目、...)。

animals = ["dog", "cat", "mouse", "rabbit", "horse"]
p animals[2..4]    # 3番目から5番目まで
p animals[2...4]   # 3番目から5番目まで、5番目は含まない
p animals[-4..-2]  # 末尾から4番目..末尾から2番目まで 
["mouse", "rabbit", "horse"]
["mouse", "rabbit"]
["cat", "mouse", "rabbit"]

ref.xaio.jp

 

・join

joinメソッドは、配列の各要素を文字列に変換し、引数sepを区切り文字として結合した文字列を返します。

引数のデフォルト値は組み込み変数$,の値です。$,の初期値はnilなので、引数を省略すると区切り文字なしで要素を結合した文字列になります。

arr = ["hello", "world", 123]
puts arr.join(", ")
puts arr.join
hello, world, 123
helloworld123

配列の中に配列が含まれるときは、平坦化して結合します。

arr = [1, 2, 3, [4, 5], [6, [7, 8]]]
puts arr.join(", ")
1, 2, 3, 4, 5, 6, 7, 8

ref.xaio.jp

 

正規表現

 /で囲む。

 /;

 

・||

 a||b

  trueだった方を返す。

 

 

 

 

ruby silver 勉強記録 (6日目)

・日付

%Y :4桁の西暦

%y:2桁の西暦

%m:月

%d:日

%H:時刻

%M:分

%S:秒

 

・ハッシュ

インスタンスメソッド

clear : ハッシュを空にする。

fetch : キーに対応する値を取り出し、キーがなければ指定の値を返す。

invert : キーを値に、値をキーにする。

 

・%、%s

%: ダブルクオートで囲う場合と同等。シングルクオートやダブルクオートのエスケープが不要になる。後述の%q()と違い、変数・定数の展開もできる。

str = %(Programming language "Ruby")
puts str
# => Programming language "Ruby"

 

%s: シンボルにする。式の展開はされない。

sym = %s(Ruby)
p sym
# => :Ruby

 

qiita.com

 

 

・contact

 concatメソッドは、配列arrayの末尾に引数の配列other_arrayを結合します。

fruits = ["apple", "orange", "banana"]
fruits.concat(["kiwi", "strawberry"])
p fruits
["apple", "orange", "banana", "kiwi", "strawberry"]

concat (Array) - Rubyリファレンス

 

・chop

 

str.chop

chopメソッドは、文字列の末尾から1文字を取り除いた新しい文字列を返します。末尾が"\r\n"で終わっている場合だけは、"\r\n"の2文字を取り除きます。

s = "hello"
puts s.chop
hell

 

・ヒアドキュメントとは

Ruby

Rubyにもヒアドキュメントが存在し、それは <<識別子 を含む行の次の行から識別子だけの行の直前までを文字列とする行指向のリテラルである[6]。例えば、

print <<EOS      # 識別子 EOS までがリテラルになる
  the string
  next line
EOS

のように書くと、以下と同じように出力される。

print "  the string\n  next line\n"

ヒアドキュメント - Wikipedia

 

・モジュールとは

まずモジュールとは何かについて見ておきましょう。モジュールは次のようなものです。

module モジュール名

end

モジュールは「module」から始まり「end」で終わりとなります。そしてモジュールにはモジュール名を指定します。

クラスの中でモジュールを利用できるようにするにはクラスの中に次のように記述します。

include モジュール名

インクルードされたモジュールはクラス内のインスタンスメソッドと同じように実行する事が出来ます。

www.rubylife.jp