0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

EC2に700万件insertする

Posted at

したい事

  • EC2のmysql(RDS)にレコードを700万件入れたい
  • できるだけ短時間で入れたい
  • 1回で入れたい

環境

  • docker-compose
  • rails(6.1)
  • localマシン: mbp 16GB
  • EC2プラン: t3.small(メモリ2GB)、DBはRDS

local 下準備

docker-compose.yml内容変更↓

version: '3'
services:
  db:
    image: mysql:5.7.34
    command: --max_allowed_packet=536870912
    environment:
      MYSQL_ROOT_PASSWORD: ${MYSQL_ROOT_PASSWORD}
    ports:
      - "4306:3306"
  web:
    build: .
    command: bash -c "rm -f tmp/pids/server.pid && bundle exec rails s -p 3000 -b '0.0.0.0'"
    environment:
      TZ: Asia/Tokyo
    volumes:
      - .:/test
    ports:
      - "3000:3000"
    depends_on:
      - db
  • ポイント: 上から5行目でmysqlのpacketを512MBに増やしている

dockerのsettingを変更↓

  • ポイント: resourceのmemoryを8GBに増やしている

localで実行

  • まずlocalで数百万のinsertをできるかを確認

  • seeds.rb内容変更↓

  • (例はcsvのデータをinsertする場合)

# frozen_string_literal: true

require "csv"

def insert_all_test
  array = []
  CSV.foreach("db/test1.csv", headers: true) do |row|
    array << {
        name: row["name"],
        created_at: Time.current,
        updated_at: Time.current
    }
  end
  User.insert_all array

  array = []
  CSV.foreach("db/test2.csv", headers: true) do |row|
    array << {
        name: row["name"],
        created_at: Time.current,
        updated_at: Time.current
    }
  end
  User.insert_all array
end

insert_all_test
  • ポイント: エラーにならない程度の量のデータを1つのループで配列に入れ、一度insert_allでDBに入れる
  • それを繰り返し
  • そのdefを、最終行のinsert_all_testで実行($ rails db:seed)する
  • これで1回でinsertできる。localでは700万件insertが約15分で完了
  • (insert_allメソッドはcreated_atとupdate_atを自動で入れないので上記のように明記する必要)

EC2 下準備

  • mysqlの環境を変更する

DBがRDSの場合

  • パラメータグループでmax_allowed_packetを変更する(今回は512MBとした)

  • デフォルトのパラメータグループの内容は変更できないので、新規で作成する必要がある

  • ポイント: 新規でパラメータグループを作成した後は、そのグループをEC2インスタンスに適用する

EC2で実行

  • $ rails db:seed RAILS_ENV=production

プラン: t3.smallの場合

  • 1つのcsvは約50万件
  • 700万件のinsertに約50分掛かった

プラン: t2.microの場合

  • 1つのcsvは約30万件(50万件ではエラー。broken pipeする)

プランがmicroでも、時間を掛ければ1回でできる

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?