WSLでelasticsearch-pluginをinstallする
pathが通っていないのかインストールできず
sudo elasticsearch-plugin install analysis-kuromoji sudo: elasticsearch-plugin: コマンドが見つかりません
/usr/share/elasticsearch/bin
に入っていた
sudo /usr/share/elasticsearch/bin/elasticsearch-plugin install analysis-kuromoji
WSLでDockerを使いMySQL5.6をインストールしてdumpデータをインポートする
WSLのUbuntuにMySQL5.6をインストールしようとしたところ、依存関係が解決できず正しくインストールや起動ができなかったのでDockerを利用してMySQL5.6を用意した手順をまとめます。
docker pullと起動
ubuntu-mysql56
を使います。
Docker Hub
docker pull danbelden/ubuntu-mysql56 docker run --name mysql56 -d -p 3306:3306 danbelden/ubuntu-mysql56
mysqlに接続
# psを確認 $ docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES e17a5f3251b2 danbelden/ubuntu-mysql56 "entrypoint.sh mysqld" 9 hours ago Up 22 minutes 0.0.0.0:3306->3306/tcp magical_mendeleev # execで接続 docker exec -it e17a5f3251b2 bash # mysql-clientを使い接続 mysql --host 127.0.0.1 --port 3306 -u root -p # databaseの作成などをする
dumpデータのインポート
dump.sqlを使いDBのインポート
mysql --host 127.0.0.1 --port 3306 -u root -p database_name< dump.sql
Rails Searchkickで circuit_breaking_exception Data too largeエラー 分割インデックスする方法
RailsアプリでSearchkickを使いElasticsearchのreindexをしようとしたところデータ量が大きすぎるとのエラー
Elasticsearch::Transport::Transport::ServerError · [429] {"error":{"root_cause":[{"type":"circuit_breaking_exception","reason":"[parent] Data too large, data for [<http_request>] would be [7474977728/6.9gb], which is larger than the limit of [7429763891/6.9gb], real usage: [7473437560/6.9gb], new bytes reserved: [1540168/1.4mb]","bytes_wanted":7474977728,"bytes_limit":7429763891,"durability":"PERMANENT"}],"type":"circuit_breaking_exception","reason":"[parent] Data too large, data for [<http_request>] would be [7474977728/6.9gb], which is larger than the limit of [7429763891/6.9gb], real usage: [7473437560/6.9gb], new bytes reserved: [1540168/1.4mb]","bytes_wanted":7474977728,"bytes_limit":7429763891,"durability":"PERMANENT"},"status":429}
Parallel Reindexingをすることバックグラウンドジョブ(今回だとSidekiqを利用)を使って解決できるらしい
GitHub - ankane/searchkick: Intelligent search made easy with Rails and Elasticsearch
Product.reindex(async: true) # indexが終わるタイミングを検知できないため # indexが終わってからaliasを書き換える Product.search_index.promote(index_name)
indexが終わるのを待って自動で切り替えまでするには
Searchkick.redis = Redis.new Product.reindex(async: {wait: true})
とのことだが永遠に続く Batches left: 1
Product.reindex(async: {wait: true}) => Enqueued Searchkick::BulkReindexJob (Job ID: 12345) to Sidekiq(searchkick) with arguments: {:class_name=>"Product", :index_name=>"products_20201109161642890", :batch_id=>1, :min_id=>1, :max_id=>1000} Created index: products_20201109161642890 Batches left: 1 Batches left: 1 Batches left: 1 Batches left: 1 Batches left: 1 ...
調査してみると Searchkick.redis = Redis.new
の設定をSidekiq側でもしないといけなかった
config/initializers/elasticsearch.rb
に以下の設定を追加することで無事 Parallel Reindexing
できました。
Searchkick.redis = Redis.new
Rails ActiveRecordで特定のカラムのユニークな配列を取得する
例えば created_on
に日付が入っているこんなデータ
Post.last Post Load (13.1ms) SELECT "posts".* FROM "posts" => #<Post id: 1, user_id: 1, created_on: "2020-11-02">
pluck
を使うだけだと同じ日付が入ってしまう
Post.pluck(:created_on) (2.7ms) SELECT "posts"."created_on" FROM "posts" => [Mon, 02 Nov 2020, Mon, 02 Nov 2020, ...]
uniq
すると一意の日付だけになる
Post.pluck(:created_on).uniq (2.7ms) SELECT "posts"."created_on" FROM "posts" => [Mon, 02 Nov 2020, Tue, 03 Nov 2020, Sat, 26 Sep 2020,
このままでもいいが posts
のレコード数が多すぎるとその分の配列を uniq
することになるのでアプリケーション側に負荷がかかる可能性があるのでDB側にやらせる
select
distinct
を使う
Post.select(:created_on).distinct.pluck(:created_on) (2.0ms) SELECT DISTINCT "posts"."created_on" FROM "posts" => [Tue, 01 Sep 2020, Wed, 02 Sep 2020, Thu, 03 Sep 2020, Fri, 04 Sep 2020, ...
これでハッピー
Rails test環境のDBを初期化する
RAILS_ENV
で test
を指定する
bundle exec rails db:migrate:reset RAILS_ENV=test
削除、作成、migrateを個別にする
bundle exec rails db:drop RAILS_ENV=test bundle exec rails db:create RAILS_ENV=test bundle exec rails db:migrate RAILS_ENV=test