はじめに
今回はSolrにおいて、アプリケーション側からコミット制御を行う際に使われるcommitWithinの挙動について紹介します。
Solrではドキュメントを追加(add)しても即座に検索に反映されず、データをいつ検索できる状態にするかを制御する必要があります。この反映タイミングを決める仕組みがcommitとcommitWithinです。
業務で大量のデータを扱う中で、アプリケーション側から明示的にcommitを多発すると、タイムアウトやパフォーマンス低下 を引き起こすケースがありました。
そこで今回は、commitWithinを使ってSolr に「◯秒以内に commit してね」と任せる方法をシンプルなコード例で紹介します!
commitとcommitWithinの違い
Solrではデータを追加しても、すぐには検索結果に反映されません。その反映タイミングを決めるのが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秒)を指定して動作を確認する簡単な例です。
namespace :solr do
desc 'commitWithin の動作確認'
task commit_within_demo: :environment do
logger = Logger.new($stdout)
solr = RSolr.connect(url: 'http://solr_blog_2:8983/solr/blog_2_core')
logger.info('==============[START] commitWithin デモ開始==============')
# ① 初期登録
solr.add({ id: 1, title: '初期登録' })
solr.commit
logger.info('初期データ登録 & commit 完了')
# ② 登録内容確認
initial = solr.get('select', params: { q: 'id:1' })['response']['docs']
logger.info("現在の検索結果: #{initial}")
# ③ commitWithin で非同期更新
solr.add({ id: 1, title: '値更新' }, params: { commitWithin: 10000 })
logger.info('commitWithin=10000ms で add 送信')
# ④ 即時検索(未反映想定)
now = solr.get('select', params: { q: 'id:1' })['response']['docs']
logger.info("即時検索結果: #{now}")
# ⑤ 5秒待って再検索(未反映想定)
sleep 5
later = solr.get('select', params: { q: 'id:1' })['response']['docs']
logger.info("5秒後の検索結果: #{later}")
# ⑥ 更に6秒待って再検索(反映想定)
sleep 6
later = solr.get('select', params: { q: 'id:1' })['response']['docs']
logger.info("6秒後の検索結果: #{later}")
logger.info('==============[FINISH] commitWithin デモ完了!==============')
end
end反映までの流れ
実際に実行してみると、以下のようなログが出力されました👇
I, [2025-10-20T07:19:41.282601 #140] INFO -- : ==============[START] commitWithin デモ開始==============
I, [2025-10-20T07:19:41.510604 #140] INFO -- : 初期データ登録 & commit 完了
I, [2025-10-20T07:19:41.520535 #140] INFO -- : 現在の検索結果: [{"id"=>"1", "title"=>["初期登録"], "_version_"=>1846484435064586240, "_root_"=>"1"}]
I, [2025-10-20T07:19:41.539103 #140] INFO -- : commitWithin=10000ms で add 送信
I, [2025-10-20T07:19:41.543181 #140] INFO -- : 即時検索結果: [{"id"=>"1", "title"=>["初期登録"], "_version_"=>1846484435064586240, "_root_"=>"1"}]
I, [2025-10-20T07:19:46.557352 #140] INFO -- : 5秒後の検索結果: [{"id"=>"1", "title"=>["初期登録"], "_version_"=>1846484435064586240, "_root_"=>"1"}]
I, [2025-10-20T07:19:52.573803 #140] INFO -- : 6秒後の検索結果: [{"id"=>"1", "title"=>["値更新"], "_version_"=>1846484435237601280, "_root_"=>"1"}]
I, [2025-10-20T07:19:52.574023 #140] INFO -- : ==============[FINISH] commitWithin デモ完了!==============結果として、即時では反映されず約10秒後に更新が反映されました。
このように、SolrはcommitWithin=10000と指定すると指定時間内にSoft Commitを実行してくれます。アプリケーション側で commitを毎回呼ばなくても、「◯秒以内に検索できるようにする」動きをSolrが保証してくれる 形です
commitwithin=1ms(0.001秒)を指定した場合
次に、commitWithinに1msという非現実的な短い値を指定した場合の挙動を見てみます。
namespace :solr do
desc 'commitWithin の動作確認(極端な値を指定した場合の挙動検証)'
task commit_within_demo_2: :environment do
logger = Logger.new($stdout)
solr = RSolr.connect(url: 'http://solr_blog_2:8983/solr/blog_2_core')
logger.info('==============[START] commitWithin デモ開始==============')
# ① 初期登録(基準データ)
solr.add({ id: 1, title: '初期登録' })
solr.commit
initial = solr.get('select', params: { q: 'id:1' })['response']['docs']
logger.info("初期登録完了 → 検索結果: #{initial}")
# ② commitWithin に1msを指定して add 送信
solr.add({ id: 1, title: '値更新(commitWithin=1ms)' }, params: { commitWithin: 1 })
logger.info('commitWithin=1ms で add 送信')
# ③ 即時検索
now = solr.get('select', params: { q: 'id:1' })['response']['docs']
logger.info("即時検索結果: #{now}")
# ④ 数秒待って再検索
sleep 2
later = solr.get('select', params: { q: 'id:1' })['response']['docs']
logger.info("2秒後の検索結果: #{later}")
logger.info('==============[FINISH] commitWithin デモ完了!==============')
end
end反映までの流れ
実際に実行してみると、以下のようなログが出力されました👇
I, [2025-10-20T07:34:29.126061 #142] INFO -- : ==============[START] commitWithin デモ開始==============
I, [2025-10-20T07:34:29.479756 #142] INFO -- : 初期登録完了 → 検索結果: [{"id"=>"1", "title"=>["初期登録"], "_version_"=>1846485366087876608, "_root_"=>"1"}]
I, [2025-10-20T07:34:29.502203 #142] INFO -- : commitWithin=1ms で add 送信
I, [2025-10-20T07:34:29.509730 #142] INFO -- : 即時検索結果: [{"id"=>"1", "title"=>["初期登録"], "_version_"=>1846485366087876608, "_root_"=>"1"}]
I, [2025-10-20T07:34:31.585763 #142] INFO -- : 2秒後の検索結果: [{"id"=>"1", "title"=>["値更新(commitWithin=1ms)"], "_version_"=>1846485366324854784, "_root_"=>"1"}]
I, [2025-10-20T07:34:31.589721 #142] INFO -- : ==============[FINISH] commitWithin デモ完了!==============結果として、エラーは発生せず正常に反映されました。
ただし、実際の反映は約1〜2秒後であり、1msで即時反映されませんでした。
…
記事の続きは下のURLをクリック!
https://rightcode.co.jp/blogs/53823
エンジニア積極採用中です!
現在、WEBエンジニア、モバイルエンジニア、デザイナー、営業などを積極採用中です!
採用ページはこちら:https://rightcode.co.jp/recruit
社員の声や社風などを知りたい方はこちら:https://rightcode.co.jp/blogs?category=life
フリーランスエンジニア大募集中!
現在、「WEBエンジニア」「フロントエンジニア」「データサイエンティスト」など、様々な職種のフリーランスエンジニア様を募集中です。まずは以下よりお気軽にご応募ください!
採用ページはこちら:https://itanken.com/register
社長と一杯飲みながらお話しませんか?(転職者向け)
特設ページはこちら: https://rightcode.co.jp/gohan-sake-president-talk
もっとワクワクしたいあなたへ
現在、ライトコードでは「WEBエンジニア」「モバイルエンジニア」「ゲームエンジニア」、「デザイナー」「WEBディレクター」「営業」などを積極採用中です!
ライトコードは技術力に定評のある受託開発をメインにしているIT企業です。
有名WEBサービスやアプリの受託開発などの企画、開発案件が目白押しの状況です。
- もっと大きなことに挑戦したい!
- エンジニアとしてもっと成長したい!
- モダンな技術に触れたい!
現状に満足していない方は、まずは、エンジニアとしても第一線を走り続ける弊社代表と気軽にお話してみませんか?
ネット上では、ちょっとユルそうな会社に感じると思いますが(笑)、
実は技術力に定評があり、沢山の実績を残している会社ということをお伝えしたいと思っております。
- ライトコードの魅力を知っていただきたい!
- 社風や文化なども知っていただきたい!
- 技術に対して熱意のある方に入社していただきたい!
一度、【Wantedly内の弊社ページ】や【コーポレートサイト】をのぞいてみてください。
Wantedly:https://www.wantedly.com/companies/rightcode
コーポレート:https://rightcode.co.jp/