Добро пожаловать в форум, Guest  >>   Войти | Регистрация | Поиск | Правила | В избранное | Подписаться
Все форумы / Java Новый топик    Ответить
 Hikari connection pool singleton factory  [new]
Molasar
Member

Откуда:
Сообщений: 700
Всем привет!

Нужна реализация Hikari connection pool singleton factory с настройкой пула через run-time HikariConfig, т.е. зашитые параметры в блоке static или jndi ресурсы не подойдут.

Приведенный ниже код работает, но не эффективен, т.к. synchronized нужен для первого обращения, после он будет только тормозить процесс.

Какой другой синглтон лучше использовать в этом случае?

public class HikariConectionFactory {
      
    private static HikariDataSource hikariDataSource = null;

    private HikariConectionFactory() {
    }

    public static synchronized Connection getConnection(HikariConfig hikariConfig)
            throws SQLException, ClassNotFoundException {
        if (hikariDataSource == null) {
            hikariDataSource = new HikariDataSource(hikariConfig);
        }
        return hikariDataSource.getConnection();
    }
}
4 июл 19, 09:47    [21920504]     Ответить | Цитировать Сообщить модератору
 Re: Hikari connection pool singleton factory  [new]
Molasar
Member

Откуда:
Сообщений: 700
Есть вариант с Double Checked Locking & volatile, но читал что этот вариант будет тормозить на многопроцессорных серверах.
4 июл 19, 09:56    [21920512]     Ответить | Цитировать Сообщить модератору
 Re: Hikari connection pool singleton factory  [new]
PetroNotC Sharp
Member

Откуда:
Сообщений: 618
Molasar,
Если крайне нужна скорость, то создавай коннект при старте потока внутри потока. Без пула.
Тогда никаких ограничений вообще не будет.
Имхо
4 июл 19, 10:18    [21920534]     Ответить | Цитировать Сообщить модератору
 Re: Hikari connection pool singleton factory  [new]
Molasar
Member

Откуда:
Сообщений: 700
C пулом Hikari получается быстрее.
Я создаю пул потоков, каждый из которых хватает connection из пула Hikari и пишет в базу.
Но для этого требуется настроить пул.
public class FlushObjectToDB implements Runnable {
    
    ...
    @Override
    public void run() {
        try (Connection connection = HikariConectionFactory.getConnection()) {
            ...
        } catch (SQLException ex) {
            throw new RuntimeException(exceptionFailedGetHikariConnection, ex);
        }
    }
}


PetroNotC Sharp
Molasar,
Если крайне нужна скорость, то создавай коннект при старте потока внутри потока. Без пула.
Тогда никаких ограничений вообще не будет.
Имхо
4 июл 19, 10:35    [21920552]     Ответить | Цитировать Сообщить модератору
 Re: Hikari connection pool singleton factory  [new]
Мозговой_слизень
Member

Откуда:
Сообщений: 3008
ну... что тут можно подсказать))) ты сам все написал вроде правильно.

public class HikariConectionFactory {
      
private static volatile HikariDataSource hikariDataSource;
private HikariConectionFactory() {    }

 if(hikariDataSource== null) 
    {        
      synchronized(HikariConectionFactory.class) 
       {            
         if(hikariDataSource== null)  
          {               
           hikariDataSource= new HikariConectionFactory ();
           } 
      } 
   } 
return hikariDataSource.getConnection();


}


ИМХО на многопроцессорных машинах усё работать должно так же как на однопроцессорной. Ибо кол-во потоков и так будет многократно превышать кол-во процессоров. То есть заданий 1000 а процессоров 8. То же самое как если бы заданий было 200 а процессор 1
4 июл 19, 10:55    [21920578]     Ответить | Цитировать Сообщить модератору
 Re: Hikari connection pool singleton factory  [new]
PetroNotC Sharp
Member

Откуда:
Сообщений: 618
Molasar
C пулом Hikari получается быстрее.
обоснуй.
Чтобы пул не ждал, MAX в пуле коннектов не менее потоков.
Если потоков 1000, и MAX 500 то будет ожидание.
Это суть пулов вообще. Они не для твоего проекта.
4 июл 19, 11:04    [21920583]     Ответить | Цитировать Сообщить модератору
 Re: Hikari connection pool singleton factory  [new]
Мозговой_слизень
Member

Откуда:
Сообщений: 3008
Вернее так:

public class HikariConectionFactory {
      
private static volatile HikariDataSource hikariDataSource;
private HikariConectionFactory() {    }

    public static Connection getInstance(HikariConfig hikariConfig)
    {

        if (hikariDataSource == null)
        {
            synchronized (HikariConectionFactory.class)
            {
                if (hikariDataSource == null)
                {
                    hikariDataSource = new HikariConectionFactory();
                }
            }
        }
        return hikariDataSource.getConnection();

    }

}
4 июл 19, 11:10    [21920589]     Ответить | Цитировать Сообщить модератору
 Re: Hikari connection pool singleton factory  [new]
Molasar
Member

Откуда:
Сообщений: 700
Это вариант - Double Checked Locking & volatile, но читал что этот вариант будет тормозить на многопроцессорных серверах.
Чтобы не тормозило нужно ввести локальную переменную:
public class HikariConectionFactoryDoubleCheck {

    private static volatile HikariDataSource hikariDataSource;

    public static synchronized Connection getConnection(
            HikariConfig hikariConfig)
            throws SQLException, ClassNotFoundException {
        HikariDataSource localHikariDataSource = hikariDataSource;
        
        if (localHikariDataSource == null) {
            synchronized (HikariConectionFactoryDoubleCheck.class) {
                localHikariDataSource = hikariDataSource;
                if (localHikariDataSource == null) {
                    hikariDataSource = localHikariDataSource 
                            = new HikariDataSource(hikariConfig);
                }
            }
        }
        return localHikariDataSource.getConnection();
    }
    
}

Мозговой_слизень
Вернее так:

public class HikariConectionFactory {
      
private static volatile HikariDataSource hikariDataSource;
private HikariConectionFactory() {    }

    public static Connection getInstance(HikariConfig hikariConfig)
    {

        if (hikariDataSource == null)
        {
            synchronized (HikariConectionFactory.class)
            {
                if (hikariDataSource == null)
                {
                    hikariDataSource = new HikariConectionFactory();
                }
            }
        }
        return hikariDataSource.getConnection();

    }

}
4 июл 19, 11:23    [21920600]     Ответить | Цитировать Сообщить модератору
 Re: Hikari connection pool singleton factory  [new]
Мозговой_слизень
Member

Откуда:
Сообщений: 3008
Да как удобней. Мне еще не понятно почему это будет тормозить. Для проверки этого утверждения неплохо было бы как-то измерить скорость. И "тормоза" понятие относительное. Где-то нужна скорость, где-то этим можно пренебречь, от проекта зависит. Метод написан корректно (по крайней мере для 8-ой джавы). А дальше уже сколько хотите столько и придумывайте как это улучшить. Если это вообще возможно.
4 июл 19, 11:42    [21920615]     Ответить | Цитировать Сообщить модератору
 Re: Hikari connection pool singleton factory  [new]
Molasar
Member

Откуда:
Сообщений: 700
Многопроцессорные сервера будут больше тратить времени на доступ к переменной volatile, чем на доступ с локальной переменной.
У меня сейчас нет возможности протестировать это на таком сервере.
Мозговой_слизень
Да как удобней. Мне еще не понятно почему это будет тормозить. Для проверки этого утверждения неплохо было бы как-то измерить скорость. И "тормоза" понятие относительное. Где-то нужна скорость, где-то этим можно пренебречь, от проекта зависит. Метод написан корректно (по крайней мере для 8-ой джавы). А дальше уже сколько хотите столько и придумывайте как это улучшить. Если это вообще возможно.
4 июл 19, 11:57    [21920628]     Ответить | Цитировать Сообщить модератору
 Re: Hikari connection pool singleton factory  [new]
забыл ник
Member

Откуда:
Сообщений: 2814
public class HikariConectionFactoryDoubleCheck {

    private static volatile HikariDataSource hikariDataSource; ----- зачем здесь volatile, если единожды установившись он не меняется

    public static synchronized Connection getConnection( -------------- первая точка синхронизации
            HikariConfig hikariConfig)
            throws SQLException, ClassNotFoundException {
        HikariDataSource localHikariDataSource = hikariDataSource;
        
        if (localHikariDataSource == null) {
            synchronized (HikariConectionFactoryDoubleCheck.class) { -------- wtf??? вторая точка синхронизации
                localHikariDataSource = hikariDataSource;
                if (localHikariDataSource == null) {
                    hikariDataSource = localHikariDataSource 
                            = new HikariDataSource(hikariConfig);
                }
            }
        }
        return localHikariDataSource.getConnection();
    }
    
}


Если сказать коротко, то это фиаско, полный треш. Вместо вполне нормального
public class HikariConectionFactory {
      
    private static HikariDataSource hikariDataSource = null;

    private HikariConectionFactory() {
    }

    public static synchronized Connection getConnection(HikariConfig hikariConfig)
            throws SQLException, ClassNotFoundException {
        if (hikariDataSource == null) {
            hikariDataSource = new HikariDataSource(hikariConfig);
        }
        return hikariDataSource.getConnection();
    }
}


вот этот вот треш с двумя синхронайзед блоками и волатайл на горячую переменную? И это предполагается быстрее? Пздц. И весь рефакторинг основан на том что ты прочитал какую то статью где говорят что синхронайзед это медленно?
Не принимай на личный счет, но с такими познаниями писать многопоточку это ужас, и вдвойне ужас что кто-то скидывает на тебя такие задачи. Я понимаю что время-деньги и программа нужна чейчас, но я даже у индусов в последнее время такого го..а не вижу.
Самое приксорбное что такое разгильдяйство везде.

Совет 1 - Читай не стать и и бложики, а хорошие проверенные книги. В твоем случае Java Concurrency in Action просто must-have, читать раза 3. Потом можно прочитать Art Of Multiprocessor programming, раз 5. В перерывах смотреть все видосы Шипилева и Куксенко, можно читать их статьи тоже. Потом можно приступать к промышленному кодированию многопоточки. Да это долго, но пока ты этого не сделаешь ты будешь плавать в потемках и имплементить поделки методом ненаучного тыка

Сщвет 2 - Пока ты работаешь над советом номер 1, старайся не "умничать" - 100% перехитришь сам себя, как в этом случае. Не делай ничего если не понимаешь последствий. В твоем случае самый первый вариант оптимальный. Вот начнет тормозить, тогда и подумаешь как исправить. С вероятностью 99.9999% тормоза будут в другом месте.

Следовать или нет советам - это дело конечно сугубо твое, но я писал их не за тем чтобы загнобить или затроллить
4 июл 19, 12:14    [21920638]     Ответить | Цитировать Сообщить модератору
 Re: Hikari connection pool singleton factory  [new]
chpasha
Member

Откуда:
Сообщений: 7988
Molasar
У меня сейчас нет возможности протестировать это на таком сервере

а мозг у тебя есть чтобы прикинуть о каких временных затратах может идти речь? Особенно по сравнению с тысячами инсертов в базу, http запросами и прочим хозяйством? Я уже один раз намекнул в другом топике, что преждевременная оптимизация вредна, особенно в случае новичков. Но ты этого либо не понял либо не сделал никаких выводов.
4 июл 19, 12:17    [21920645]     Ответить | Цитировать Сообщить модератору
 Re: Hikari connection pool singleton factory  [new]
PetroNotC Sharp
Member

Откуда:
Сообщений: 618
chpasha
Molasar
У меня сейчас нет возможности протестировать это на таком сервере

а мозг у тебя есть чтобы прикинуть о каких временных затратах может идти речь? Особенно по сравнению с тысячами инсертов в базу, http запросами и прочим хозяйством? Я уже один раз намекнул в другом топике, что преждевременная оптимизация вредна, особенно в случае новичков. Но ты этого либо не понял либо не сделал никаких выводов.
+1
4 июл 19, 12:25    [21920652]     Ответить | Цитировать Сообщить модератору
 Re: Hikari connection pool singleton factory  [new]
Molasar
Member

Откуда:
Сообщений: 700
Первая точка синхронизации не нужна конечно. Случайно добавил.
Про volatile может быть вы и правы. Своё мнение сложилось после прочтения статьи http://www.cs.umd.edu/~pugh/java/memoryModel/DoubleCheckedLocking.html

Вообще без обид. Я всегда с большим уважением отношусь к советам и критике, на этом форуме от более просвещенных коллег.
Эти книги уже скачал) В ближайшее время буду читать.


забыл ник
public class HikariConectionFactoryDoubleCheck {

    private static volatile HikariDataSource hikariDataSource; ----- зачем здесь volatile, если единожды установившись он не меняется

    public static synchronized Connection getConnection( -------------- первая точка синхронизации
            HikariConfig hikariConfig)
            throws SQLException, ClassNotFoundException {
        HikariDataSource localHikariDataSource = hikariDataSource;
        
        if (localHikariDataSource == null) {
            synchronized (HikariConectionFactoryDoubleCheck.class) { -------- wtf??? вторая точка синхронизации
                localHikariDataSource = hikariDataSource;
                if (localHikariDataSource == null) {
                    hikariDataSource = localHikariDataSource 
                            = new HikariDataSource(hikariConfig);
                }
            }
        }
        return localHikariDataSource.getConnection();
    }
    
}


Если сказать коротко, то это фиаско, полный треш. Вместо вполне нормального
public class HikariConectionFactory {
      
    private static HikariDataSource hikariDataSource = null;

    private HikariConectionFactory() {
    }

    public static synchronized Connection getConnection(HikariConfig hikariConfig)
            throws SQLException, ClassNotFoundException {
        if (hikariDataSource == null) {
            hikariDataSource = new HikariDataSource(hikariConfig);
        }
        return hikariDataSource.getConnection();
    }
}


вот этот вот треш с двумя синхронайзед блоками и волатайл на горячую переменную? И это предполагается быстрее? Пздц. И весь рефакторинг основан на том что ты прочитал какую то статью где говорят что синхронайзед это медленно?
Не принимай на личный счет, но с такими познаниями писать многопоточку это ужас, и вдвойне ужас что кто-то скидывает на тебя такие задачи. Я понимаю что время-деньги и программа нужна чейчас, но я даже у индусов в последнее время такого го..а не вижу.
Самое приксорбное что такое разгильдяйство везде.

Совет 1 - Читай не стать и и бложики, а хорошие проверенные книги. В твоем случае Java Concurrency in Action просто must-have, читать раза 3. Потом можно прочитать Art Of Multiprocessor programming, раз 5. В перерывах смотреть все видосы Шипилева и Куксенко, можно читать их статьи тоже. Потом можно приступать к промышленному кодированию многопоточки. Да это долго, но пока ты этого не сделаешь ты будешь плавать в потемках и имплементить поделки методом ненаучного тыка

Сщвет 2 - Пока ты работаешь над советом номер 1, старайся не "умничать" - 100% перехитришь сам себя, как в этом случае. Не делай ничего если не понимаешь последствий. В твоем случае самый первый вариант оптимальный. Вот начнет тормозить, тогда и подумаешь как исправить. С вероятностью 99.9999% тормоза будут в другом месте.

Следовать или нет советам - это дело конечно сугубо твое, но я писал их не за тем чтобы загнобить или затроллить
4 июл 19, 12:29    [21920657]     Ответить | Цитировать Сообщить модератору
 Re: Hikari connection pool singleton factory  [new]
Molasar
Member

Откуда:
Сообщений: 700
Да, я помню твой совет. Спасибо.
Но на текущий момент я сделал свою часть проекта раньше других. Есть время поэкспериментировать над производительностью, чтобы в будущем можно было использовать. Чем это плохо?
chpasha
Molasar
У меня сейчас нет возможности протестировать это на таком сервере

а мозг у тебя есть чтобы прикинуть о каких временных затратах может идти речь? Особенно по сравнению с тысячами инсертов в базу, http запросами и прочим хозяйством? Я уже один раз намекнул в другом топике, что преждевременная оптимизация вредна, особенно в случае новичков. Но ты этого либо не понял либо не сделал никаких выводов.
4 июл 19, 12:36    [21920669]     Ответить | Цитировать Сообщить модератору
 Re: Hikari connection pool singleton factory  [new]
Molasar
Member

Откуда:
Сообщений: 700
Простой тест на моей клиентской машине для разных реализаций синглтона (nTimes = 100 000 000):
        long start = System.currentTimeMillis();
        for (int i = 0; i < nTimes; i++) {
            Connection connection
                    = HikariConectionFactorySynchronized
                            .getConnection(hikariConfig);
            connection.close();
        }
        System.out.println(nTimes 
                + " connections by Synchronized factory takes: "
                + (System.currentTimeMillis() - start));


DoubleCheck&Volatile + LocalVar: 7386 millis
DoubleCheck&Volatile: 7449 millis
Synchronized: 8585 millis

Мозговой_слизень
Да как удобней. Мне еще не понятно почему это будет тормозить. Для проверки этого утверждения неплохо было бы как-то измерить скорость. И "тормоза" понятие относительное. Где-то нужна скорость, где-то этим можно пренебречь, от проекта зависит. Метод написан корректно (по крайней мере для 8-ой джавы). А дальше уже сколько хотите столько и придумывайте как это улучшить. Если это вообще возможно.
4 июл 19, 12:44    [21920683]     Ответить | Цитировать Сообщить модератору
 Re: Hikari connection pool singleton factory  [new]
PetroNotC Sharp
Member

Откуда:
Сообщений: 618
Molasar
Простой тест на моей
а где 1000 потоков конкурирующих к пулу?
Что тестировал?
4 июл 19, 13:14    [21920703]     Ответить | Цитировать Сообщить модератору
 Re: Hikari connection pool singleton factory  [new]
PetroNotC Sharp
Member

Откуда:
Сообщений: 618
Molasar
Чем это плохо?
тем что тестировать надо то что пишешь.
Написал секцию синхронизации, и сразу тест НА ЭТУ СЕКЦИЮ. Чтобы она тормознула 999 потоков и пропустила только один.
4 июл 19, 13:17    [21920707]     Ответить | Цитировать Сообщить модератору
 Re: Hikari connection pool singleton factory  [new]
Lelouch
Member

Откуда: Москва
Сообщений: 1721
Molasar,

Посмотрите вот этот доклад про JMM:


Переменную в Double Checked Lock обычно вводят вместо volatile, чтобы получить безопасную гонку.
4 июл 19, 14:02    [21920757]     Ответить | Цитировать Сообщить модератору
 Re: Hikari connection pool singleton factory  [new]
Андрей Панфилов
Member

Откуда: Москва > Melbourne
Сообщений: 3249
Molasar,

у вас идея изначально неверная, что размер JDBC-пула должен каким-то образом соотноситься с количеством ядер. Правильная идея: размер пула должен быть строго больше количества потоков, которые из этого пула могут тягать соединения. Почему так? Вот несколько довольно распространенных тем:
- паттерн, что мы можем из одного потока создать несколько соединений вполне нормальный: в одном месте мы что-то делаем в одной транзакции, а в другом месте мы хотим что-то сделать в другой транзакции, не закрывая первую
- поток, который взял соединение из пула может при выполнении наткнуться на критическую секцию в коде/обращение к тормозным внешним ресурсам/и пр., поэтому будет получаться, что кто-то ждет когда поток вернет соединение, а сам поток ждет чего-то другого

поэтому выставлять размер JDBC-пула меньше чем количество потоков можно только тогда, когда вы полностью контролируете весь код и всегда знаете что и где происходит, в противном случае размер JDBC-пула должен быть больше количества потоков.
4 июл 19, 14:08    [21920766]     Ответить | Цитировать Сообщить модератору
 Re: Hikari connection pool singleton factory  [new]
PetroNotC Sharp
Member

Откуда:
Сообщений: 618
Андрей Панфилов,
Как всегда правы.
4 июл 19, 14:27    [21920791]     Ответить | Цитировать Сообщить модератору
 Re: Hikari connection pool singleton factory  [new]
Мозговой_слизень
Member

Откуда:
Сообщений: 3008
Ну то есть,как я понял, автор изначально написал нормальный код. Мы его тут немного улучшили with Double‐Checked locking, но он об этом и так догадывался.
А если не секрет, автор, ты из какого города и сколько ЗП?
4 июл 19, 16:41    [21920935]     Ответить | Цитировать Сообщить модератору
 Re: Hikari connection pool singleton factory  [new]
Мозговой_слизень
Member

Откуда:
Сообщений: 3008
Мозговой_слизень
Ну то есть,как я понял, автор изначально написал нормальный код. Мы его тут немного улучшили with Double‐Checked locking, но он об этом и так догадывался.
А если не секрет, автор, ты из какого города и сколько ЗП?

блин, там просто смайлик должен быть обычный
4 июл 19, 16:41    [21920938]     Ответить | Цитировать Сообщить модератору
 Re: Hikari connection pool singleton factory  [new]
забыл ник
Member

Откуда:
Сообщений: 2814
Мозговой_слизень, Нормальным рещением проблемы было бы инициализировать DataSource в точке старта приложения и передавать его в конструктор ConnectionFactory, HikariDataSource hikariDataSource --- сделать final и забыть о синхронизации насовсем.
А в данном случае была решена непонятная проблема по-любому не лучшим, но сносным способом.
4 июл 19, 17:36    [21920995]     Ответить | Цитировать Сообщить модератору
Все форумы / Java Ответить