Невообразимая скорость сокетов в Oracle JVM

1

Я работаю с Oracle, и меня просят ускорить работу над устаревшим приложением. Для этого ускорения мне нужен какой-то одномоментный сингл, содержащий временные данные; в настоящее время эти данные хранятся в постоянных таблицах базы данных и накладывают большую нагрузку на базу данных. Временные таблицы не могут использоваться из-за многосеансового доступа к данным.

Я попытался сделать этот синглтон использующим хранимую Java. Основная проблема, которую я нашел - Oracle делает что-то вроде отдельного JVM для каждого сеанса базы данных (https://docs.oracle.com/cd/B28359_01/java.111/b31225/chtwo.htm#BABBDCDI), поэтому Singleton не может быть доступен через общие Память.

Я делаю некоторые API, содержащие "сервер" (singleton) и "client" (методы доступа). Клиент связывается с сервером через локальные сокеты. Поскольку однопоточный характер сохраненного Java (https://docs.oracle.com/cd/B28359_01/java.111/b31225/chtwo.htm#BABHHHDG) сервера принимает и обрабатывает запросы в один поток, подобный этому (упрощенный):

    ServerSocket socket = new ServerSocket(..., InetAddress.getByName(null));
    while (!finished) {
      Socket client = socket.accept();
      ..
      output.println(process(input));
      ..
      client.close();
    }

Клиент отправляет запрос следующим образом:

  Socket socket = new Socket(InetAddress.getByName(null), getPort(requestId));
  ..
  for (int i = 0; i < data.length; i++) output.println(data[i]);
  String result = in.readLine();
  ..
  socket.close();

В то время как runnings тестирует как автономное приложение Java, без Oracle, он работает так на моей рабочей станции:

34001 звонков в 3.178 сек.

Avg. 10698.86721208307 звонков в секунду

Avg. время ожидания: 0.03199905885121026 мс.

Avg. время процесса: 0.0628510926149231 ms.

Это общеприемлемо. Но при загрузке в Oracle такой тест показывает совсем другую скорость:

117 звонков в 24.218 сек.

Avg. 4.831117350730861 звонков в секунду

Avg. время ожидания: 90.17094017094017 мс.

Avg. время процесса: 203.54700854700855 мс.

Почему это так медленно? Что я могу сделать, чтобы исправить эту бессмыслицу? Есть ли лучший способ общения между сеансами в Oracle/jvm?

  • 1
    Медлительность - это, скорее всего, «проблема с самим собой», или, более конкретно, проблема вашей конкретной среды, и поэтому трудно сказать, что делать, когда на самом деле нечего делать. Нет деталей конфигурации, нет описания среды, нет ничего. Всем известно, что вы используете базу данных на виртуальной машине с сильно ограниченной пропускной способностью ввода-вывода. Вы также не детализируете, что вы связываете между базами данных, поэтому также невозможно дать какой-либо совет о том, что может быть лучшей стратегией (плюс, что само собой разумеющееся). Oracle Advanced Queuing приходит на ум, как дикая догадка.
  • 0
    ОС, на которой работает oracle DB, также сильно влияет на производительность. Ваши данные в том виде, в котором они представлены, не имеют большого значения с точки зрения получения помощи или предложений. Есть ли у вас статистика perf для OS - длины запросов очереди ввода / вывода и т. Д.? Это явно выглядит как возможная проблема с ОС или слушателем. Проверьте журнал слушателя на машине оракула.
Показать ещё 2 комментария
Теги:
sockets
jvm

1 ответ

1

В результате расследования.

  1. Администраторы не сказали ничего интересного о длительности запросов квестов и/или запросов.

  2. Внутренняя Java-система Oracle в несколько раз медленнее, чем автономная. Я написал простой пример, в котором конвертирует целое число в строку и помещает его в карту; он работает примерно в 4 раза медленнее в хранимой процедуре. Пенальти различается для различных операций.

  3. Я профилировал класс. Используя различные методы (nodelay, повторное использование сокетов, потоков), я достиг примерно в 8 раз быстрее в автономном приложении и примерно в 100 раз быстрее в сохраненной Java, это было ограничение, которое я могу сделать.

  4. В этот момент я отказался от сохраненного-java-only. Я начал автономное приложение с частью сервера рядом с базой данных и настроил клиентскую часть в базу данных для ее подключения. Это дает мне скорость, необходимую мне; в этом случае эффективная скорость составляет около 80% автономного приложения. Эта скорость для меня достаточно; он остановился, чтобы стать узким местом.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню