Migrate search to Searchkick gem.#3199
Conversation
| gem "unicorn", "~> 5.8.0" | ||
| gem "validates_formatting_of" | ||
| gem "elasticsearch", "~> 7.10.1" | ||
| gem "elasticsearch-api", "~> 7.10.1" |
There was a problem hiding this comment.
I have removed explicit api/transport requirement since we don't use it directly and it is already dependency of elasticsearch gem.
Codecov Report
@@ Coverage Diff @@
## master #3199 +/- ##
==========================================
- Coverage 98.52% 98.45% -0.07%
==========================================
Files 113 110 -3
Lines 3390 3302 -88
==========================================
- Hits 3340 3251 -89
- Misses 50 51 +1
Help us with your feedback. Take ten seconds to tell us how you rate us. Have a feature suggestion? Share it here. |
| end | ||
|
|
||
| def update_search_index | ||
| @version.rubygem.delay.update_document |
There was a problem hiding this comment.
Is there any alternative to update_document in searchkick @ankane?
There was a problem hiding this comment.
It's not exactly the same, but there is partial reindexing.
| Rubygem.searchkick_index.create | ||
| end | ||
|
|
||
| task :import_alias do |
There was a problem hiding this comment.
Online async import is supported in Searchkick by default https://github.com/ankane/searchkick#parallel-reindexing, but I wasn't able to setup it locally without adding Redis dependency. Anyway since we don't need reindexing currently, I just made it simple.
In production we can call:
index = Rubygem.reindex(mode: :async)
# wait once done
Rubygem.searchkick_index.promote(index[:index_name])There was a problem hiding this comment.
We used this task for upgrades (which required new index for backward incompatible change) or fix/add some data from our end.
Creating a new index and updating the alias allowed us to do this without downtime. Creating new index takes considerable amount of time.
There was a problem hiding this comment.
As I mentioned, we can do the same and it is built in. Searchkick utilizes ActiveJob we doesn't really use currently. But I have plan to move all .delay calls to proper background jobs soon as well. For now we can do async reindexing as mentioned. Not reindexing is needed when deployed since the using index is exactly the same (checked manually via API).
There was a problem hiding this comment.
For now we can do async reindexing as mentioned.
Does this work without redis? I think somewhere you commented that async needs redis.
There was a problem hiding this comment.
Yes, redis is needed just for optional progress tracking AFAIK.
| end | ||
|
|
||
| def update_search_index | ||
| @version.rubygem.delay.update_document |
There was a problem hiding this comment.
It's not exactly the same, but there is partial reindexing.
| end | ||
| Delayed::Job.enqueue Indexer.new, priority: PRIORITIES[:push] | ||
| rubygem.delay.index_document | ||
| rubygem.delay.reindex |
There was a problem hiding this comment.
fwiw, delay.reindex isn't tested in Searchkick (the recommended approach is reindex(mode: :async))
There was a problem hiding this comment.
This just calls rubygem.reindex in backround job. That should be safe.
There was a problem hiding this comment.
We don't use ActiveJob for now, but I have plan to migrate from delay job being used directly to ActiveJob. Once done, we can move to reindex(mode: :async) if I understand it well.
|
Also, forgot to mention Searchkick has built-in Rake tasks for reindexing, you might be able to remove rake searchkick:reindex:all
# or
rake searchkick:reindex CLASS=Rubygem |
432dcff to
87a70e3
Compare
|
@ankane would you mind to do another review round once you have some spare time 🙏? |
|
Hey @simi, looks great! While not needed with the current code (since it only calls |
d1c8609 to
49676f4
Compare
|
This is ready from my side @sonalkr132 @jenshenny. Next step would be to merge and test on staging. |
| @@ -482,10 +480,7 @@ DEPENDENCIES | |||
| delayed_job | |||
| delayed_job_active_record | |||
| elasticsearch (~> 7.10.1) | |||
There was a problem hiding this comment.
Do we have plans to remove this? I am guessing we can't upgrade our cluster as long as we have this in out gemfile.
There was a problem hiding this comment.
Yes, plan is to move to OpenSearch gems once this lands to production.
There was a problem hiding this comment.
Can you please elaborate on the order of changes?
- deploy this to prod
- replace elasticsearch in gemfile with opensearch (does opensearch gem work with ES cluster)
- upgrade ES cluster engine in staging to opensearch
Is this the plan?
There was a problem hiding this comment.
Once this will be merged, deployed to staging and considered safe to deploy to production, we can deploy to production.
After that my plan is to open other PR moving out of elasticsearch gem (migrate to opensearch). That can be merged and tested on staging as well. There is no need for upgrade of ES cluster.
And again after some time we can finally upgrade ES cluster engine. First I would like to try on staging to see if any downtime is needed and get some estimate on time needed for upgrade in general and repeat in production. If I understand it well, application works well without ES. The only problem could be unindexed changes. We can track gems recently changed (during maintenance window) and explicitly ask for reindex for those.
That's my initial plan.
|
I have tested this on staging (manually deploying this branch in there). Everything works well with no needed for reindexing. I have tested reindexing as well.
ℹ️ this wipes the index first so search is affected by this time kubectl exec -it deploy/unicorn -n rubygems-staging --context rubygems -- bin/rake searchkick:reindex CLASS=Rubygem
Defaulted container "unicorn" out of: unicorn, nginx
** [Honeybadger] Initializing Honeybadger Error Tracker for Ruby. Ship it! version=5.0.2 framework=rails level=1 pid=32
Reindexing Rubygem...
Reindex successful
real 40m21,265s
user 0m1,088s
sys 0m0,490s
ℹ️ is needed to be merged #3266 for this ℹ️ this is not affecting search functionality # schedule reindex in batches using ActiveJob
index = Rubygem.reindex(mode: :async)
#=> {:index_name=>"rubygems-staging_20221113223835766"}
# check progress
Delayed::Backend::ActiveRecord::Job.where(queue: 'searchkick').count
#=> 175
# switch
Rubygem.searchkick_index.promote(index[:index_name])
#=> {"acknowledged"=>true} |
|
I think this is ready for merge. |
- removes elasticsearch-rails dependency not supporting opensearch
|
🙌 |
ℹ️ Once we migrate to searchkick (or fix the non-existing opensearch-rails gem problem), I can continue on upgrading tech stack at AWS to latest OpenSearch version.