title: Elastic gives inconsistent results under stress
body: <p>Our ES is fairly slow, we did not optimize it (and the query) yet, but according to <a href="https://www.elastic.co/guide/en/elasticsearch/guide/current/_monitoring_individual_nodes.html#_threadpool_section" rel="nofollow noreferrer">this link</a>, request rejection from Elastic is a form of a feedback that asks to slow down and adapt the size of the bulk.</p>
  
  <p>We built a form of a back pressure where the size of a blocking bulk (a list of individual requests sent at the same time, we do not use MSearch yet) depends on how many requests were rejected in the previous bulk. We wait for current bulk to finish before starting a new one. Obviously all rejected requests are re-injected into the request-queue (in a form of a data needed to construct the query). For example if our Elastic can handle 500 simultaneous requests and we send 600, some of them will be rejected and the new size will be reduced to 480 (20% off).</p>
  
  <p>What we found out was that <strong>ES returns different results for the previously rejected requests</strong>. For example it may return something like the expected result, but with an offset of 2. We also have missing results where an address should have 1 result, but has none due to this bug.</p>
  
  <p>If the bulk size is less than the threshold that ES can handle, everything goes as expected and we get expected results.</p>
  
  <p>It doesn't look like it's the library's (elastic4s) problem.</p>
  
  <p>Elastic configuration:
  2 nodes with 5 shards each</p>
  
  <p>Per node:
  2 CPU, 32 GB ram, 16 GB heap. Everything else is default</p>
  
  <p>I couldn't find any information on the internet, did anyone have this problem? What was the solution?</p>
  
  <p>What we tried so far:</p>
  
  <ul>
  <li><p><code>Thread.sleep</code> between bulks as the link above suggests.</p></li>
  <li><p>Removing cache on query level as well as removing it from the index.</p></li>
  <li><p>Trying same index on a different (slower) hardware.</p></li>
  <li><p>Verified that it's not a race-condition (in our code) problem.</p></li>
  </ul>
  
  <p>Update:</p>
  
  <p>What <a href="https://github.com/ONSdigital/address-index-api/blob/ee631d70d634bec5039ae05bfa0bef5e3f474b2e/server/test/uk/gov/ons/addressIndex/server/modules/ElasticsearchRepositorySpec.scala#L385" rel="nofollow noreferrer">the query</a> like.</p>
  
  <p>Thread pool for search:
  <code>
     "search" : {
            "type" : "fixed",
            "min" : 4,
            "max" : 4,
            "queue_size" : 1000
          },
  </code></p>
  
  <p>2nd UPDATE:</p>
  
  <p>We also tried setting preference to our query (thinking that it was a problem with shards): <code>.preference(Preference.Primary)</code> with no positive result (they were even more random than before). Two consecutive runs with this setting give different "random" results, so this is not consistent.</p>