WSL Elasticsearchの起動ができない java.lang.IllegalArgumentException: Plugin [analysis-kuromoji] was built for Elasticsearch version 7.8.0 but version 7.10.0 is running

こんなエラーが出た

java.lang.IllegalArgumentException: Plugin [analysis-kuromoji] was built for Elasticsearch version 7.8.0 but version 7.10.0 is running

$ sudo service elasticsearch restart
 * Starting Elasticsearch Server                                                                                        uncaught exception in thread [main]
java.lang.IllegalArgumentException: Plugin [analysis-kuromoji] was built for Elasticsearch version 7.8.0 but version 7.10.0 is running
        at org.elasticsearch.plugins.PluginsService.verifyCompatibility(PluginsService.java:352)
        at org.elasticsearch.plugins.PluginsService.loadBundle(PluginsService.java:622)
        at org.elasticsearch.plugins.PluginsService.loadBundles(PluginsService.java:479)
        at org.elasticsearch.plugins.PluginsService.<init>(PluginsService.java:168)
        at org.elasticsearch.node.Node.<init>(Node.java:346)
        at org.elasticsearch.node.Node.<init>(Node.java:289)
        at org.elasticsearch.bootstrap.Bootstrap$5.<init>(Bootstrap.java:227)
        at org.elasticsearch.bootstrap.Bootstrap.setup(Bootstrap.java:227)
        at org.elasticsearch.bootstrap.Bootstrap.init(Bootstrap.java:393)
        at org.elasticsearch.bootstrap.Elasticsearch.init(Elasticsearch.java:170)
        at org.elasticsearch.bootstrap.Elasticsearch.execute(Elasticsearch.java:161)
        at org.elasticsearch.cli.EnvironmentAwareCommand.execute(EnvironmentAwareCommand.java:86)
        at org.elasticsearch.cli.Command.mainWithoutErrorHandling(Command.java:127)
        at org.elasticsearch.cli.Command.main(Command.java:90)
        at org.elasticsearch.bootstrap.Elasticsearch.main(Elasticsearch.java:126)
        at org.elasticsearch.bootstrap.Elasticsearch.main(Elasticsearch.java:92)
For complete error details, refer to the log at /var/log/elasticsearch/elasticsearch.log
                                                                                                                 [fail]

プラグインの対応バージョンが違うらしい
Elasticsearchをアップデートだけしてプラグインが古いままのよう
一旦removeしてインストールし直す

sudo /usr/share/elasticsearch/bin/plugin remove analysis-kuromoji
sudo /usr/share/elasticsearch/bin/plugin install analysis-kuromoji

起動成功

$ sudo service elasticsearch restart
 * Starting Elasticsearch Server                                                                                 [ OK ]

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, ...

これでハッピー