20211127のMySQLに関する記事は1件です。

EC2に700万件insertする

したい事 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回でできる
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む