zelastic 0.8.0 → 0.9.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.github/workflows/ci.yml +45 -0
- data/CODEOWNERS +5 -0
- data/README.md +39 -0
- data/lib/zelastic/index_manager.rb +38 -0
- data/lib/zelastic/indexer.rb +4 -3
- data/lib/zelastic/version.rb +1 -1
- data/zelastic.gemspec +1 -1
- metadata +7 -9
- data/.circleci/config.yml +0 -48
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: be9663f3819fc9057a838604106173e90e8b48219542a67eeac5f6493e696921
|
|
4
|
+
data.tar.gz: 67c3775b7911527728fc417c1978e223155d73bb7ade42629d8c595f2fcb0193
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 668853db1e94c690e8a86c32b1de997d11563d531cdef95b8f9dcab49df74ac412e36d2b79832ff12bcd82a8dc7740ca0afaa76acf82af2a83efb12e2d55f15d
|
|
7
|
+
data.tar.gz: e2e6f75c50b0c763654136fdf753e0734c0d79f5112f467c5f4fa6142cb332272595eecf1061120e82110bfd18ae08e0215fe205090cf35c23ea03b461fe6b98
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
name: CI
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
branches: [main, master]
|
|
6
|
+
pull_request:
|
|
7
|
+
branches: [main, master]
|
|
8
|
+
|
|
9
|
+
jobs:
|
|
10
|
+
test:
|
|
11
|
+
name: ES ${{ matrix.elasticsearch }} / Gem ${{ matrix.elasticsearch_gem }}
|
|
12
|
+
runs-on: ubuntu-latest
|
|
13
|
+
|
|
14
|
+
strategy:
|
|
15
|
+
fail-fast: false
|
|
16
|
+
matrix:
|
|
17
|
+
elasticsearch: ["8.3.3"]
|
|
18
|
+
elasticsearch_gem: ["~> 8", "~> 7"]
|
|
19
|
+
include:
|
|
20
|
+
- elasticsearch: "7.17.5"
|
|
21
|
+
elasticsearch_gem: "~> 7"
|
|
22
|
+
|
|
23
|
+
services:
|
|
24
|
+
elasticsearch:
|
|
25
|
+
image: elasticsearch:${{ matrix.elasticsearch }}
|
|
26
|
+
env:
|
|
27
|
+
discovery.type: single-node
|
|
28
|
+
xpack.security.enabled: "false"
|
|
29
|
+
ports:
|
|
30
|
+
- 9200:9200
|
|
31
|
+
options: --health-cmd "curl -s http://localhost:9200" --health-interval 5s --health-timeout 3s --health-retries 20
|
|
32
|
+
|
|
33
|
+
env:
|
|
34
|
+
ELASTICSEARCH_GEM_VERSION: ${{ matrix.elasticsearch_gem }}
|
|
35
|
+
|
|
36
|
+
steps:
|
|
37
|
+
- uses: actions/checkout@v4
|
|
38
|
+
|
|
39
|
+
- uses: ruby/setup-ruby@v1
|
|
40
|
+
with:
|
|
41
|
+
ruby-version: "3.4"
|
|
42
|
+
bundler-cache: true
|
|
43
|
+
|
|
44
|
+
- run: bin/rubocop
|
|
45
|
+
- run: bin/rspec
|
data/CODEOWNERS
ADDED
data/README.md
CHANGED
|
@@ -102,6 +102,45 @@ The `client` keyword argument to `Zelastic::IndexManager.new` is optional. It de
|
|
|
102
102
|
passed to `Zelastic::Config.new`, if one client is passed, or the first client in the array, if an
|
|
103
103
|
array is passed to `Zelastic::Config.new`.
|
|
104
104
|
|
|
105
|
+
### Reindexing using Elasticsearch's Reindex API
|
|
106
|
+
|
|
107
|
+
For large indices, you can use Elasticsearch's native reindex API instead of `populate_index`:
|
|
108
|
+
|
|
109
|
+
```ruby
|
|
110
|
+
index_manager = Zelastic::IndexManager.new(MyModelIndex)
|
|
111
|
+
source_index = index_manager.current_read_index
|
|
112
|
+
dest_index = index_manager.current_write_index # or any target index name
|
|
113
|
+
index_manager.reindex(source_index: source_index, dest_index: dest_index)
|
|
114
|
+
```
|
|
115
|
+
|
|
116
|
+
### Reindexing from a remote Elasticsearch instance
|
|
117
|
+
|
|
118
|
+
If you have multiple Elasticsearch instances (e.g., primary and secondary), you can copy data
|
|
119
|
+
from one to another using the `reindex_from_remote` method:
|
|
120
|
+
|
|
121
|
+
```ruby
|
|
122
|
+
# On the destination ES instance
|
|
123
|
+
secondary_client = Elasticsearch::Client.new(url: ENV['SECONDARY_ELASTICSEARCH_URL'])
|
|
124
|
+
index_manager = Zelastic::IndexManager.new(MyModelIndex, client: secondary_client)
|
|
125
|
+
|
|
126
|
+
# Get the source index name from the primary instance
|
|
127
|
+
primary_client = Elasticsearch::Client.new(url: ENV['ELASTICSEARCH_URL'])
|
|
128
|
+
source_index = primary_client.indices.get_alias(name: MyModelIndex.read_alias).keys.first
|
|
129
|
+
|
|
130
|
+
dest_index = index_manager.current_write_index
|
|
131
|
+
index_manager.reindex_from_remote(
|
|
132
|
+
source_host: ENV['ELASTICSEARCH_URL'],
|
|
133
|
+
source_index: source_index,
|
|
134
|
+
dest_index: dest_index,
|
|
135
|
+
username: ENV['ELASTICSEARCH_USERNAME'], # optional
|
|
136
|
+
password: ENV['ELASTICSEARCH_PASSWORD'], # optional
|
|
137
|
+
wait_for_completion: false # runs asynchronously by default
|
|
138
|
+
)
|
|
139
|
+
```
|
|
140
|
+
|
|
141
|
+
Note: For remote reindexing to work, the destination Elasticsearch cluster must have the source
|
|
142
|
+
host configured in `reindex.remote.whitelist` in `elasticsearch.yml`.
|
|
143
|
+
|
|
105
144
|
## Development
|
|
106
145
|
|
|
107
146
|
After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake spec` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
|
|
@@ -92,12 +92,50 @@ module Zelastic
|
|
|
92
92
|
client.indices.delete(index: indices_to_delete)
|
|
93
93
|
end
|
|
94
94
|
|
|
95
|
+
def reindex_from_local(source_index:, dest_index:, wait_for_completion: false)
|
|
96
|
+
logger.info("Reindexing from #{source_index} to #{dest_index}")
|
|
97
|
+
reindex(source: { index: source_index }, dest_index: dest_index,
|
|
98
|
+
wait_for_completion: wait_for_completion
|
|
99
|
+
)
|
|
100
|
+
end
|
|
101
|
+
|
|
102
|
+
def reindex_from_remote(source_host:, source_index:, dest_index:,
|
|
103
|
+
username: nil, password: nil, wait_for_completion: false)
|
|
104
|
+
logger.info("Reindexing from remote #{source_host}/#{source_index} to #{dest_index}")
|
|
105
|
+
|
|
106
|
+
remote = { host: source_host }
|
|
107
|
+
remote[:username] = username if username
|
|
108
|
+
remote[:password] = password if password
|
|
109
|
+
|
|
110
|
+
reindex(source: { remote: remote, index: source_index }, dest_index: dest_index,
|
|
111
|
+
wait_for_completion: wait_for_completion
|
|
112
|
+
)
|
|
113
|
+
end
|
|
114
|
+
|
|
115
|
+
def current_read_index
|
|
116
|
+
client.indices.get_alias(name: config.read_alias).keys.first
|
|
117
|
+
end
|
|
118
|
+
|
|
119
|
+
def current_write_index
|
|
120
|
+
client.indices.get_alias(name: config.write_alias).keys.first
|
|
121
|
+
end
|
|
122
|
+
|
|
95
123
|
private
|
|
96
124
|
|
|
97
125
|
attr_reader :config, :client
|
|
98
126
|
|
|
99
127
|
def_delegators :config, :logger
|
|
100
128
|
|
|
129
|
+
def reindex(source:, dest_index:, wait_for_completion:)
|
|
130
|
+
client.reindex(
|
|
131
|
+
body: {
|
|
132
|
+
source: source,
|
|
133
|
+
dest: { index: dest_index }
|
|
134
|
+
},
|
|
135
|
+
wait_for_completion: wait_for_completion
|
|
136
|
+
)
|
|
137
|
+
end
|
|
138
|
+
|
|
101
139
|
def indexer
|
|
102
140
|
@indexer ||= Indexer.new(config)
|
|
103
141
|
end
|
data/lib/zelastic/indexer.rb
CHANGED
|
@@ -13,6 +13,10 @@ module Zelastic
|
|
|
13
13
|
|
|
14
14
|
extend Forwardable
|
|
15
15
|
|
|
16
|
+
VERSION_CONFLICT_ERROR_REGEXP =
|
|
17
|
+
/^\[\d+\]: version conflict, current version \[\d+\] is higher or equal to the one provided \[\d+\]$/
|
|
18
|
+
private_constant :VERSION_CONFLICT_ERROR_REGEXP
|
|
19
|
+
|
|
16
20
|
def initialize(config)
|
|
17
21
|
@config = config
|
|
18
22
|
end
|
|
@@ -118,8 +122,5 @@ module Zelastic
|
|
|
118
122
|
error['type'] == 'version_conflict_engine_exception' &&
|
|
119
123
|
error['reason'] =~ VERSION_CONFLICT_ERROR_REGEXP
|
|
120
124
|
end
|
|
121
|
-
|
|
122
|
-
VERSION_CONFLICT_ERROR_REGEXP =
|
|
123
|
-
/^\[\d+\]: version conflict, current version \[\d+\] is higher or equal to the one provided \[\d+\]$/.freeze
|
|
124
125
|
end
|
|
125
126
|
end
|
data/lib/zelastic/version.rb
CHANGED
data/zelastic.gemspec
CHANGED
|
@@ -28,7 +28,7 @@ Gem::Specification.new do |spec|
|
|
|
28
28
|
spec.add_dependency 'activesupport'
|
|
29
29
|
|
|
30
30
|
spec.add_development_dependency 'bundler', '~> 2'
|
|
31
|
-
spec.add_development_dependency 'carwow_rubocop', '~>
|
|
31
|
+
spec.add_development_dependency 'carwow_rubocop', '~> 6'
|
|
32
32
|
spec.add_development_dependency 'pry', '~> 0.14'
|
|
33
33
|
spec.add_development_dependency 'rake', '~> 13'
|
|
34
34
|
spec.add_development_dependency 'rspec', '~> 3'
|
metadata
CHANGED
|
@@ -1,14 +1,13 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: zelastic
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 0.9.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- carwow Developers
|
|
8
|
-
autorequire:
|
|
9
8
|
bindir: exe
|
|
10
9
|
cert_chain: []
|
|
11
|
-
date:
|
|
10
|
+
date: 1980-01-02 00:00:00.000000000 Z
|
|
12
11
|
dependencies:
|
|
13
12
|
- !ruby/object:Gem::Dependency
|
|
14
13
|
name: elasticsearch
|
|
@@ -78,14 +77,14 @@ dependencies:
|
|
|
78
77
|
requirements:
|
|
79
78
|
- - "~>"
|
|
80
79
|
- !ruby/object:Gem::Version
|
|
81
|
-
version: '
|
|
80
|
+
version: '6'
|
|
82
81
|
type: :development
|
|
83
82
|
prerelease: false
|
|
84
83
|
version_requirements: !ruby/object:Gem::Requirement
|
|
85
84
|
requirements:
|
|
86
85
|
- - "~>"
|
|
87
86
|
- !ruby/object:Gem::Version
|
|
88
|
-
version: '
|
|
87
|
+
version: '6'
|
|
89
88
|
- !ruby/object:Gem::Dependency
|
|
90
89
|
name: pry
|
|
91
90
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -135,12 +134,13 @@ executables: []
|
|
|
135
134
|
extensions: []
|
|
136
135
|
extra_rdoc_files: []
|
|
137
136
|
files:
|
|
138
|
-
- ".circleci/config.yml"
|
|
139
137
|
- ".github/dependabot.yml"
|
|
138
|
+
- ".github/workflows/ci.yml"
|
|
140
139
|
- ".gitignore"
|
|
141
140
|
- ".rspec"
|
|
142
141
|
- ".rubocop.yml"
|
|
143
142
|
- CHANGELOG.md
|
|
143
|
+
- CODEOWNERS
|
|
144
144
|
- Gemfile
|
|
145
145
|
- LICENSE.txt
|
|
146
146
|
- README.md
|
|
@@ -160,7 +160,6 @@ homepage: https://github.com/carwow/zelastic
|
|
|
160
160
|
licenses:
|
|
161
161
|
- MIT
|
|
162
162
|
metadata: {}
|
|
163
|
-
post_install_message:
|
|
164
163
|
rdoc_options: []
|
|
165
164
|
require_paths:
|
|
166
165
|
- lib
|
|
@@ -175,8 +174,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
175
174
|
- !ruby/object:Gem::Version
|
|
176
175
|
version: '0'
|
|
177
176
|
requirements: []
|
|
178
|
-
rubygems_version:
|
|
179
|
-
signing_key:
|
|
177
|
+
rubygems_version: 4.0.3
|
|
180
178
|
specification_version: 4
|
|
181
179
|
summary: Zero-downtime (re-)indexing of ActiveRecord models into Elasticsearch.
|
|
182
180
|
test_files: []
|
data/.circleci/config.yml
DELETED
|
@@ -1,48 +0,0 @@
|
|
|
1
|
-
version: 2.1
|
|
2
|
-
|
|
3
|
-
jobs:
|
|
4
|
-
test:
|
|
5
|
-
parameters:
|
|
6
|
-
ruby_version:
|
|
7
|
-
type: string
|
|
8
|
-
elasticsearch_version:
|
|
9
|
-
type: string
|
|
10
|
-
elasticsearch_gem_version:
|
|
11
|
-
type: string
|
|
12
|
-
docker:
|
|
13
|
-
- image: "cimg/ruby:<< parameters.ruby_version >>"
|
|
14
|
-
- image: "elasticsearch:<< parameters.elasticsearch_version >>"
|
|
15
|
-
environment:
|
|
16
|
-
"discovery.type": single-node
|
|
17
|
-
"xpack.security.enabled": false
|
|
18
|
-
environment:
|
|
19
|
-
ELASTICSEARCH_GEM_VERSION: "<< parameters.elasticsearch_gem_version >>"
|
|
20
|
-
steps:
|
|
21
|
-
- checkout
|
|
22
|
-
- run: bin/setup
|
|
23
|
-
- run: bin/rubocop
|
|
24
|
-
- run: dockerize -wait http://localhost:9200 -timeout 1m
|
|
25
|
-
- run: bin/rspec
|
|
26
|
-
|
|
27
|
-
workflows:
|
|
28
|
-
version: 2
|
|
29
|
-
test:
|
|
30
|
-
jobs:
|
|
31
|
-
- test:
|
|
32
|
-
name: "test with elasticsearch v8
|
|
33
|
-
and gem << matrix.elasticsearch_gem_version >>
|
|
34
|
-
and ruby v<< matrix.ruby_version >>"
|
|
35
|
-
elasticsearch_version: "8.3.3"
|
|
36
|
-
matrix:
|
|
37
|
-
parameters:
|
|
38
|
-
ruby_version: ["3.1", "2.7"]
|
|
39
|
-
elasticsearch_gem_version: ["~> 8", "~> 7"]
|
|
40
|
-
- test:
|
|
41
|
-
name: "test with elasticsearch v7
|
|
42
|
-
and gem << matrix.elasticsearch_gem_version >>
|
|
43
|
-
and ruby v<< matrix.ruby_version >>"
|
|
44
|
-
elasticsearch_version: "7.17.5"
|
|
45
|
-
matrix:
|
|
46
|
-
parameters:
|
|
47
|
-
ruby_version: ["3.1", "2.7"]
|
|
48
|
-
elasticsearch_gem_version: ["~> 7"]
|