Операция Couchbase Get замедляется при увеличении количества входящих потоков - PullRequest
0 голосов
/ 20 ноября 2018

Резюме:

У нас есть серьезная проблема с производительностью Spring-Boot 2.0.4 и Couchbase server 5.5.1

Мы наблюдаем быстрое снижение производительности времени отклика БД, когдаколичество потоков увеличивается. Вот еще одно сообщение о проблеме .

Подробнее:

Spring Boot работает с 500 потоками:

server:
  tomcat:
    max-threads: 500
    max-connections: 500

Мы используем следующую зависимость:

     <dependency>
        <groupId>org.springframework.data</groupId>
        <artifactId>spring-data-couchbase</artifactId>
        <version>3.0.9.RELEASE</version>
    </dependency>

Наш "выбор" из БД выполняется с помощью репозитория Spring-Data:

Cat findFirstByOwnerIdAndNameAndColor(String ownerId, String name, String color);

У нас есть индекс, специально для этогоquery:

CREATE INDEX `cat_by_ownerId_name_and_color_idx` ON `pets`(`ownerId`,`name`,`color`) WHERE (`_class` = "com.example.Cat")

По мере увеличения количества запросов мы можем наблюдать быстрое снижение времени, которое требуется БД для ответа на запрос.

Например, при выполнении 300 запросов наво-вторых, процентиль времени ответа 99 составляет около 10 секунд !! , а процентиль 50 составляет около 5 секунд.

Средний размер возвращаемого документа составляет около 300 байт .Это означает, что мы пытаемся извлечь около 90 килобайт в секунду.Относительно небольшая сумма.

Редактировать:

Я добавляю сюда результат выполнения того же запроса в пользовательском интерфейсе Couchbase: (В пользовательском интерфейсе запросзанимает 1,75 мс).

{
 "plan": {
  "#operator": "Sequence",
  "~children": [
  {
    "#operator": "IndexScan3",
    "index": "cats_by_ownerId_name_and_color_idx",
    "index_id": "c061141c2d373067",
    "index_projection": {
      "primary_key": true
    },
    "keyspace": "pets",
    "namespace": "default",
    "spans": [
      {
        "exact": true,
        "range": [
          {
            "high": "\"bf23fa4c-22c3-42ac-b141-39cdc76bb2x5\"",
            "inclusion": 3,
            "low": "\"bf23fa4c-22c3-42ac-b141-39cdc76bb2x5\""
          },
          {
            "high": "\"Oscar\"",
            "inclusion": 3,
            "low": "\"Oscar\""
          },
          {
            "high": "\"red\"",
            "inclusion": 3,
            "low": "\"red\""
          }
        ]
      }
    ],
    "using": "gsi"
  },
  {
    "#operator": "Fetch",
    "keyspace": "pets",
    "namespace": "default"
  },
  {
    "#operator": "Parallel",
    "~child": {
      "#operator": "Sequence",
      "~children": [
        {
          "#operator": "Filter",
          "condition": "(((((`pets`.`_class`) = \"com.example.Cat\") and ((`pets`.`ownerId`) = \"bf23fa4c-22c3-42ac-b141-39cdc76bb2x5\")) and ((`pets`.`name`) = \"Oscar\")) and ((`pets`.`color`) = \"red\"))"
        },
        {
          "#operator": "InitialProject",
          "result_terms": [
            {
              "expr": "self",
              "star": true
            }
          ]
        },
        {
          "#operator": "FinalProject"
        }
      ]
    }
  }
]
 },
 "text": "select * from pets where _class=\"com.example.Cat\" and projectId=\"bf23fa4c-22c3-42ac-b141-39cdc76bb2x5\" and name=\"Oscar\" and color=\"red\""

}

РЕДАКТИРОВАТЬ 2

Мы также пытались неявно написать запрос N1ql, но результатта же.Как и раньше, мы получаем много TimeOutExceptions:

   Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed; nested exception is org.springframework.dao.QueryTimeoutException: java.util.concurrent.TimeoutException: {"b":"pets","s":"n1ql","t":7500000,"i":"f8cdf670-d32a-4d74-858c-f9dd9789d264"}; nested exception is java.lang.RuntimeException: java.util.concurrent.TimeoutException: {"b":"pets","s":"n1ql","t":7500000,"i":"f8cdf670-d32a-4d74-858c-f9dd9789d264"}] with root cause

java.util.concurrent.TimeoutException: {"b":"pets","s":"n1ql","t":7500000,"i":"f8cdf670-d32a-4d74-858c-f9dd9789d264"}
   at com.couchbase.client.java.bucket.api.Utils$1.call(Utils.java:131) ~[java-client-2.7.0.jar:na]
   at com.couchbase.client.java.bucket.api.Utils$1.call(Utils.java:127) ~[java-client-2.7.0.jar:na]
   at rx.internal.operators.OperatorOnErrorResumeNextViaFunction$4.onError(OperatorOnErrorResumeNextViaFunction.java:140) ~[rxjava-1.3.8.jar:1.3.8]
   at rx.internal.operators.OnSubscribeTimeoutTimedWithFallback$TimeoutMainSubscriber.onTimeout(OnSubscribeTimeoutTimedWithFallback.java:166) ~[rxjava-1.3.8.jar:1.3.8]
   at rx.internal.operators.OnSubscribeTimeoutTimedWithFallback$TimeoutMainSubscriber$TimeoutTask.call(OnSubscribeTimeoutTimedWithFallback.java:191) ~[rxjava-1.3.8.jar:1.3.8]
   at rx.internal.schedulers.ScheduledAction.run(ScheduledAction.java:55) ~[rxjava-1.3.8.jar:1.3.8]
   at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511) ~[na:1.8.0_161]
   at java.util.concurrent.FutureTask.run(FutureTask.java:266) ~[na:1.8.0_161]
   at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.access$201(ScheduledThreadPoolExecutor.java:180) ~[na:1.8.0_161]
   at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:293) ~[na:1.8.0_161]
   at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149) ~[na:1.8.0_161]
   at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624) ~[na:1.8.0_161]
   at java.lang.Thread.run(Thread.java:748) [na:1.8.0_161]

Есть ли способ это исправить, или нам нужна другая БД?

1 Ответ

0 голосов
/ 25 ноября 2018

Таким образом, после дальнейшего изучения проблема была обнаружена в компоненте Spring-Data.

Чтобы ее преодолеть, нам пришлось перейти на неблокирующий механизм .

Мы сделали 2 вещи:

  • Все вызовы со уровня контроллера до уровней обслуживания и хранилища были изменены на CompleteableFuture<Cat>
  • Для обходаПри подключении Spring-Data к базе данных couchbase мы создали собственный класс репозитория с кодом реализации, который выглядит примерно так:

    Statement statement = select("*")
            .from(i(bucket.name()))
            .where(x("name").eq(s(name))
                    .and(x("ownerId").eq(s(ownerId)))
                    .and(x("color").eq(s(color)))
                    .and(x("_class").eq(s("com.example.Cat"))));
    
    CompletableFuture<Cat> completableFuture = new CompletableFuture();
    bucket.async().query(statement)
    ...
    

    После того, как мы это сделали, проблема с задержкой исчезла, а производительность составила около 2 миллисекунды для запроса, даже при нескольких сотнях одновременных запросов.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...