Solr で commitWithin を使ってみた
IT技術
はじめに
今回はSolrにおいて、アプリケーション側からコミット制御を行う際に使われるcommitWithinの挙動について紹介します。
Solrではドキュメントを追加(add)しても即座に検索に反映されず、データをいつ検索できる状態にするかを制御する必要があります。この反映タイミングを決める仕組みがcommitとcommitWithinです。
業務で大量のデータを扱う中で、アプリケーション側から明示的にcommitを多発すると、タイムアウトやパフォーマンス低下 を引き起こすケースがありました。
そこで今回は、commitWithinを使ってSolr に「◯秒以内に commit してね」と任せる方法をシンプルなコード例で紹介します!
commitとcommitWithinの違い
Solrではデータを追加しても、すぐには検索結果に反映されません。その反映タイミングを決めるのがcommitとcommitWithin です。
| 項目 | commit | commitWithin |
| タイミング | 即時反映 | 指定時間以内に反映 |
| 処理方式 | 同期 | 非同期 |
| 向いている場面 | 少量データ | 大量データ・バッチ処理 |
commit は「今すぐ検索に反映して!」という命令。
一方 commitWithinは「今すぐじゃなくていいから、◯秒以内に反映してね」とSolrに任せる命令です。
大量データを扱うときは、アプリケーション側で細かくcommitを制御するよりも、commitWithinでSolrに任せる方が安定して動作し、一定時間後には確実に反映 されます。
commitWithinがHard CommitではなくSoft Commitなのか
commitWithinは「一定時間以内に検索可能にする」ための機能であり、検索反映の保証を目的としています。
一方で、Hard Commitはディスクへの永続化を伴う重い処理であり、頻繁に実行するとSolr全体のパフォーマンスが大きく低下してしまいます。
そのため、commitWithinは検索反映に適したSoft Commitを使用され永続化はautoCommit(定期的に実行されるHard Commit)が担当するという明確な役割分担になっています。
コード例:commitWithinを10秒で指定してみる
commitWithin を使うと、Solrに「◯秒以内に検索可能にしてね」と伝えることができます。
以下のコードは、commitWithin=10000(10秒)を指定して動作を確認する簡単な例です。
1namespace :solr do
2 desc 'commitWithin の動作確認'
3 task commit_within_demo: :environment do
4 logger = Logger.new($stdout)
5 solr = RSolr.connect(url: 'http://solr_blog_2:8983/solr/blog_2_core')
6
7 logger.info('==============[START] commitWithin デモ開始==============')
8
9 # ① 初期登録
10 solr.add({ id: 1, title: '初期登録' })
11 solr.commit
12 logger.info('初期データ登録 & commit 完了')
13
14 # ② 登録内容確認
15 initial = solr.get('select', params: { q: 'id:1' })['response']['docs']
16 logger.info("現在の検索結果: #{initial}")
17
18 # ③ commitWithin で非同期更新
19 solr.add({ id: 1, title: '値更新' }, params: { commitWithin: 10000 })
20 logger.info('commitWithin=10000ms で add 送信')
21
22 # ④ 即時検索(未反映想定)
23 now = solr.get('select', params: { q: 'id:1' })['response']['docs']
24 logger.info("即時検索結果: #{now}")
25
26 # ⑤ 5秒待って再検索(未反映想定)
27 sleep 5
28 later = solr.get('select', params: { q: 'id:1' })['response']['docs']
29 logger.info("5秒後の検索結果: #{later}")
30
31 # ⑥ 更に6秒待って再検索(反映想定)
32 sleep 6
33 later = solr.get('select', params: { q: 'id:1' })['response']['docs']
34 logger.info("6秒後の検索結果: #{later}")
35
36 logger.info('==============[FINISH] commitWithin デモ完了!==============')
37 end
38end反映までの流れ
実際に実行してみると、以下のようなログが出力されました👇
1I, [2025-10-20T07:19:41.282601 #140] INFO -- : ==============[START] commitWithin デモ開始==============
2I, [2025-10-20T07:19:41.510604 #140] INFO -- : 初期データ登録 & commit 完了
3I, [2025-10-20T07:19:41.520535 #140] INFO -- : 現在の検索結果: [{"id"=>"1", "title"=>["初期登録"], "_version_"=>1846484435064586240, "_root_"=>"1"}]
4I, [2025-10-20T07:19:41.539103 #140] INFO -- : commitWithin=10000ms で add 送信
5I, [2025-10-20T07:19:41.543181 #140] INFO -- : 即時検索結果: [{"id"=>"1", "title"=>["初期登録"], "_version_"=>1846484435064586240, "_root_"=>"1"}]
6I, [2025-10-20T07:19:46.557352 #140] INFO -- : 5秒後の検索結果: [{"id"=>"1", "title"=>["初期登録"], "_version_"=>1846484435064586240, "_root_"=>"1"}]
7I, [2025-10-20T07:19:52.573803 #140] INFO -- : 6秒後の検索結果: [{"id"=>"1", "title"=>["値更新"], "_version_"=>1846484435237601280, "_root_"=>"1"}]
8I, [2025-10-20T07:19:52.574023 #140] INFO -- : ==============[FINISH] commitWithin デモ完了!==============結果として、即時では反映されず約10秒後に更新が反映されました。
このように、SolrはcommitWithin=10000と指定すると指定時間内にSoft Commitを実行してくれます。アプリケーション側で commitを毎回呼ばなくても、「◯秒以内に検索できるようにする」動きをSolrが保証してくれる 形です
commitwithin=1ms(0.001秒)を指定した場合
次に、commitWithinに1msという非現実的な短い値を指定した場合の挙動を見てみます。
1namespace :solr do
2 desc 'commitWithin の動作確認(極端な値を指定した場合の挙動検証)'
3 task commit_within_demo_2: :environment do
4 logger = Logger.new($stdout)
5 solr = RSolr.connect(url: 'http://solr_blog_2:8983/solr/blog_2_core')
6
7 logger.info('==============[START] commitWithin デモ開始==============')
8
9 # ① 初期登録(基準データ)
10 solr.add({ id: 1, title: '初期登録' })
11 solr.commit
12 initial = solr.get('select', params: { q: 'id:1' })['response']['docs']
13 logger.info("初期登録完了 → 検索結果: #{initial}")
14
15 # ② commitWithin に1msを指定して add 送信
16 solr.add({ id: 1, title: '値更新(commitWithin=1ms)' }, params: { commitWithin: 1 })
17 logger.info('commitWithin=1ms で add 送信')
18
19 # ③ 即時検索
20 now = solr.get('select', params: { q: 'id:1' })['response']['docs']
21 logger.info("即時検索結果: #{now}")
22
23 # ④ 数秒待って再検索
24 sleep 2
25 later = solr.get('select', params: { q: 'id:1' })['response']['docs']
26 logger.info("2秒後の検索結果: #{later}")
27
28 logger.info('==============[FINISH] commitWithin デモ完了!==============')
29 end
30end反映までの流れ
実際に実行してみると、以下のようなログが出力されました👇
1I, [2025-10-20T07:34:29.126061 #142] INFO -- : ==============[START] commitWithin デモ開始==============
2I, [2025-10-20T07:34:29.479756 #142] INFO -- : 初期登録完了 → 検索結果: [{"id"=>"1", "title"=>["初期登録"], "_version_"=>1846485366087876608, "_root_"=>"1"}]
3I, [2025-10-20T07:34:29.502203 #142] INFO -- : commitWithin=1ms で add 送信
4I, [2025-10-20T07:34:29.509730 #142] INFO -- : 即時検索結果: [{"id"=>"1", "title"=>["初期登録"], "_version_"=>1846485366087876608, "_root_"=>"1"}]
5I, [2025-10-20T07:34:31.585763 #142] INFO -- : 2秒後の検索結果: [{"id"=>"1", "title"=>["値更新(commitWithin=1ms)"], "_version_"=>1846485366324854784, "_root_"=>"1"}]
6I, [2025-10-20T07:34:31.589721 #142] INFO -- : ==============[FINISH] commitWithin デモ完了!==============結果として、エラーは発生せず正常に反映されました。
ただし、実際の反映は約1〜2秒後であり、1msで即時反映されませんでした。
⚠️ 注意:commitWithinはSoft Commit(永続化はされない)
commitWithin が実行するのはSoft Commitであり、これは「検索結果に反映させるための更新」であって、ディスクへの永続化(Hard Commit)ではありません。
Soft Commit後すぐにSolrを再起動すると、反映済みに見えていたデータが失われる可能性があります。
本番環境では通常、autoCommit(例:15秒ごとなど)で定期的にHard Commitが走る設定になっていますが、もし commitWithin のみで運用している場合は、永続化の保証がない点に注意が必要です。
まとめ
今回紹介したコードは、commitWithinの動きを理解するためのシンプルなデモです。実際の業務シナリオでも、Solrへの更新頻度やデータ量に応じてcommit と commitWithin を使い分けることで、安定したパフォーマンスと反映タイミングの最適化 が実現できます。
ライトコードでは、エンジニアを積極採用中!
ライトコードでは、エンジニアを積極採用しています!カジュアル面談等もございますので、くわしくは採用情報をご確認ください。
採用情報へ




