비동기 jdbc 호출이 가능한가?
데이터베이스에 비동기식 전화를 걸 수 있는 방법이 없을까?
예를 들어, 처리 시간이 매우 오래 걸리는 큰 요청이 있다고 가정해 보십시오. 요청을 보내고 요청이 값을 반환할 때(수신기/콜백 또는 기타를 통과하여) 알림을 받고 싶습니다.데이터베이스가 응답하기를 기다리는 것을 차단하고 싶지 않다.
스레드 풀을 사용하는 것은 확장되지 않기 때문에 해결책이라고 생각하지 않는다. 동시 요청이 많은 경우 이는 매우 많은 수의 스레드를 발생시킬 것이다.
우리는 네트워크 서버에서 이런 종류의 문제에 직면하고 있으며, 우리는 연결당 하나의 스레드가 없는 것을 피하기 위해 선택/폴링/epoll 시스템 호출을 사용하여 해결책을 찾았다.데이터베이스 요청과 유사한 기능을 어떻게 사용할 수 있는지 궁금해서 그래.
참고: Fixed(고정) 사용스레드풀은 좋은 해결책일 수 있지만, 아무도 정말로 비동기적인 시스템을 개발하지 않았다는 것이 놀랍다.
** 업데이트 ** **
실질적인 실질적인 해결책의 부족 때문에, 나는 스스로 도서관(피나글의 일부분)을 만들기로 결심했다: 피나글-mysql.기본적으로 mysql 요청/대응을 디코딩/결정하며, 후드 아래에서 Finagle/Netty를 사용한다.그것은 엄청난 수의 연결에도 불구하고 매우 잘 확장된다.
나는 JDBC 호출을 포함하는 제안된 접근법 중 어떤 것이 여기에서 어떻게 도움이 되는지 이해할 수 없다. 즉, 누군가가 명확히 할 수 있다.
확실히 기본적인 문제는 소켓 IO의 JDBC 운영 블록이다.이렇게 하면 이야기의 끝에서 스레드가 흐르도록 차단된다.어떤 래핑 프레임워크를 사용하든, 하나의 스레드가 사용 중이거나 동시에 요청될 때마다 차단될 것이다.
If the underlying database drivers (MySql?) offers a means to intercept the socket creation (see SocketFactory) then I imagine it would be possible to build an async event driven database layer on top of the JDBC api but we'd have to encapsulate the whole JDBC behind an event driven facade, and that facade wouldn't look like JDBC (after it would be이벤트 중심의데이터베이스 처리는 호출자와 다른 스레드에서 비동기식으로 수행되며, 스레드 선호도에 의존하지 않는 트랜잭션 관리자를 구축하는 방법을 강구해야 할 것이다.
내가 언급한 접근법 같은 것은 단 하나의 배경 스레드라도 동시에 JDBC 임원의 부하를 처리할 수 있게 해준다.실제로 여러 코어를 사용하기 위해 스레드 풀을 실행할 수 있을 것이다.
(물론 나는 차단 소켓 IO가 있는 시나리오에서의 동시성이 선택기 패턴 사용자 없이도 가능하다는 것을 암시하는 응답들, 즉 전형적인 JDBC 동시성을 계산하고 적절한 크기의 연결 풀에 넣는 것만으로 충분하다는 것을 의미하는 응답들만을 논하는 것이 아니다.)
MySql은 아마도 내가 제안하는 선에 따라 무언가를 하는 것 같다 --- http://code.google.com/p/async-mysql-connector/wiki/UsageExample
JDBC를 통해 데이터베이스에 비동기식 통화를 하는 것은 불가능하지만, 행위자와 함께 JDBC에 비동기식 통화를 할 수 있다(예: 행위자가 JDBC를 통해 DB에 전화를 하고, 통화가 끝나면 제3자에게 메시지를 보낸다), 또는 CPS를 좋아하는 경우 파이프라인 선물(약속)과 함께 (좋은 구현은 Scalaz Promise)을 통해 할 수 있다.
스레드 풀을 사용하는 것은 확장되지 않기 때문에 해결책이라고 생각하지 않는다. 동시 요청이 많은 경우 이는 매우 많은 수의 스레드를 발생시킬 것이다.
스칼라 액터는 기본적으로 스레드가 아닌 이벤트 기반이다. 연속 스케줄링을 통해 표준 JVM 설정에서 수백만 명의 액터를 만들 수 있다.
Java를 목표로 한다면 Akka Framework는 Java와 Scala를 위한 API가 좋은 Actor 모델 구현이다.
그것과는 별개로, JDBC의 동기적 성격은 나에게 완벽히 이치에 맞는다.데이터베이스 세션 비용은 Java 스레드가 차단되어 응답을 기다리는 비용보다 훨씬 높다.쿼리가 너무 오래 실행되어 실행자 서비스(또는 실행자/fork-join/프로미션 동시성 프레임워크 포함)의 기능이 충분하지 않은 경우(또는 너무 많은 스레드를 사용 중) 먼저 데이터베이스 로드에 대해 생각해 보십시오.일반적으로 데이터베이스의 응답은 매우 빠르게 이루어지며, 고정된 스레드 풀로 지원되는 실행자 서비스는 충분한 해결책이 된다.장시간 실행 쿼리가 너무 많은 경우, 야간 데이터 재계산이나 그와 같은 선행(사전) 처리를 고려해야 한다.
아마도 당신은 꽤 잘 확장되는 JMS 비동기 메시지 시스템을 사용할 수 있을 것이다.
구독자가 메시지를 수락할 큐에 메시지를 보내고 SQL 프로세스를 실행하십시오.기본 프로세스는 계속 실행되며 새 요청을 수락하거나 전송한다.
SQL 프로세스가 종료되면 반대 방향으로 실행될 수 있다. 즉, 프로세스 결과가 포함된 ResponseQueue에 메시지를 전송하면 클라이언트 쪽의 수신자가 이를 수락하고 콜백 코드를 실행한다.
새로운 비동기식 jdbc API "다음 JDBC"가 작업 중인 것으로 보인다.
여기에서 프레젠테이션을 참조하십시오.
여기서 API를 다운로드할 수 있다.
업데이트:
- 이 새로운 jdbc API는 후에 ADBA라는 이름이 붙여졌다.그 후 2019년 9월에 메일링 리스트 포스트를 볼 수 있는 작업이 중단되었다.
- R2DBC도 비슷한 목표를 달성하는 것 같다.이미 대부분의 주요 데이터베이스(오라클 db 제외)를 지원한다.이 프로젝트는 jdk의 일부가 아닌 라이브러리라는 점에 유의하십시오.
JDBC에서는 직접 지원이 없지만, 당신은 MDB, Java 5의 실행자 같은 여러 옵션을 가지고 있다.
"나는 스레드 풀을 사용하는 것이 확장되지 않기 때문에 해결책이라고 생각하지 않는다. 동시 요청이 많은 경우 이는 매우 많은 수의 스레드를 발생시킬 것이다."
나는 왜 경계선인 실 풀이 확장되지 않는지 궁금하다.각 요청에 따라 스레드를 생성하는 것은 요청당 스레드가 아닌 풀입니다.나는 이것을 무거운 웹앱에서 꽤 오랫동안 사용해 왔고 우리는 지금까지 어떤 문제도 보지 못했다.
다른 답변에서 언급했듯이 JDBC API는 그 성격상 비동기적이지 않다.
그러나 작업의 하위 집합과 다른 API를 사용하여 생활할 수 있는 경우 솔루션이 있다.MySQL과 Postgre에서 작동하는 https://github.com/jasync-sql/jasync-sql이 한 예다.SQL
표준 관계형 데이터베이스와의 사후 대응적 연결을 가능하게 하는 솔루션이 개발되고 있다.
관계형 데이터베이스 사용량을 유지하면서 확장을 원하는 사람들은 기존 I/O 차단에 기반한 표준 때문에 대응형 프로그래밍에서 단절된다.R2DBC는 관계형 데이터베이스에서 효율적으로 작동하는 대응형 코드를 허용하는 새로운 API를 지정한다.
R2DBC는 데이터베이스 드라이버 구현자 및 클라이언트 라이브러리 작성자를 위한 비차단 SPI를 정의하는 SQL 데이터베이스로 대응 프로그래밍을 위해 처음부터 설계된 규격이다.R2DBC 드라이버는 비차단 I/O 계층 위에 데이터베이스 와이어 프로토콜을 완전히 구현한다.
R2DBC 웹 사이트
R2DBC GitHub
피쳐 매트릭스
Ajdbc 프로젝트는 이 문제에 대해 http://code.google.com/p/adbcj/으로 답한 것으로 보인다.
현재 mysql과 postgresql에 대해 기본적으로 2개의 실험 비동기 드라이버가 있다.
오래된 질문이지만 더 많은 정보가 있어벤더가 JDBC에 대한 확장과 JDBC를 처리할 래퍼를 제공하지 않는 한, JDBC가 데이터베이스 자체에 비동기 요청을 발행하도록 하는 것은 불가능하다.즉, JDBC 자체를 처리 대기열로 포장하고, 하나 이상의 별도 연결에서 대기열을 처리할 수 있는 논리를 구현할 수 있다.일부 유형의 통화에 대해 이것의 한 가지 이점은, 로직이 충분히 무거운 부하를 받는 경우, 통화를 처리를 위한 JDBC 일괄 처리로 변환하여 로직을 상당히 빠르게 할 수 있다는 것이다.이것은 데이터를 삽입하고 있는 호출에 가장 유용하며, 실제 결과는 오류가 있는 경우에만 기록하면 된다.이것의 좋은 예는 사용자 활동을 기록하기 위해 삽입이 수행되고 있는 경우 이다.애플리케이션은 통화가 즉시 완료되는지 몇 초 후에 완료되는지는 상관하지 않을 것이다.
참고로 시중에 나와 있는 한 제품은 내가 비동기적으로 만들었다고 설명한 것과 같은 비동기적 통화를 허용하는 정책 중심 접근방식을 제공한다(http://www.heimdalldata.com/)).고지 사항:나는 이 회사의 공동창업자야.JDBC 데이터 소스에 대한 삽입/업데이트/삭제 등의 데이터 변환 요청에 정규식을 적용할 수 있도록 하고, 처리를 위해 자동으로 일괄 처리한다.MySQL 및 rewriteBatchedStatements 옵션(RewriteBatchedStatements=true가 포함된 MySQL 및 JDBC)과 함께 사용하면 데이터베이스에 대한 전체 로드를 크게 줄일 수 있다.
내 생각에 넌 세가지 선택권이 있어:
- 동시 대기열을 사용하여 메시지를 적은 수의 스레드에 분산하십시오.따라서 1000개의 연결이 있다면 1000개의 스레드가 아니라 4개의 스레드가 있을 것이다.
- 다른 노드(즉, 다른 프로세스 또는 컴퓨터)에서 데이터베이스 액세스를 수행하고 데이터베이스 클라이언트가 해당 노드에 비동기식 네트워크 호출을 수행하도록 하십시오.
- 비동기 메시지를 통해 진정한 분산 시스템 구현그러기 위해서는 CoralMQ나 Tibco와 같은 메시지 큐가 필요할 것이다.
디카임베이어:나는 CoralMQ의 개발자 중 한 명이다.
장기간 실행되는 작업을 처리하기 위해 고정된 수의 스레드를 가질 수 있다.그리고 대신에Runnable
사용할 수 있다Callable
결과를 반환할 수 있는 것.결과는 물체에 캡슐화되어 있으므로, 물체가 돌아왔을 때 얻을 수 있다.
다음은 JavaOne에서 제공하는 Oracle에서 non-dbc api가 어떤 모습일 수 있는지에 대한 개요: https://static.rainfocus.com/oracle/oow16/sess/1461693351182001EmRq/ppt/CONF1578%2020160916.pdf
그래서 결국 진정한 비동기 JDBC 통화는 정말로 가능할 것으로 보인다.
단지 이상한 생각: JBDC 결과 위에 Itrelatee 패턴을 사용할 수 있음미래/약속서에 포장된 세트
해머스미스는 몽고DB를 위해 그렇게 한다.
나는 단지 여기서 아이디어를 생각하고 있다.스레드가 있는 각 데이터베이스 연결 풀과 연결하지 못한 이유각 스레드는 대기열에 접근할 수 있다.시간이 오래 걸리는 질의를 하고 싶을 때는 큐에 올려 놓으면 한 가닥의 실이 그것을 집어서 처리한다.네 실의 수가 한정되어 있기 때문에, 너는 결코 실을 많이 가질 수 없을 것이다.
편집: 또는 더 나은 방법은 스레드 몇 개뿐입니다.실이 대기열에 있는 것을 보면 풀에 연결을 요청하여 처리한다.
커먼즈드부틸즈 도서관은 ...에 대한 지원을 가지고 있다.AsyncQueryRunner
당신이 제공하는 것ExecutorService
로 그리고 그것은 a를 되돌려준다.Future
가 있다 사용이 간편하고 리소스를 유출하지 않도록 하기 때문에 체크아웃할 가치가 있다.
Java용 비동기 데이터베이스 API에 관심이 있다면 Completetable을 기반으로 한 일련의 표준 APIs를 제안하는 새로운 이니셔티브가 있음을 알아야 한다.미래와 람다.또한 JDBC를 통해 이러한 API를 구현하여 이러한 API를 연습할 수 있다: https://github.com/oracle/oracle-db-examples/tree/master/java/AoJ 자바Doc은 github 프로젝트의 README에 언급되어 있다.
참조URL: https://stackoverflow.com/questions/4087696/is-asynchronous-jdbc-call-possible
'programing' 카테고리의 다른 글
소수점 자리 n개로 부동 소수점 형식 지정 (0) | 2022.05.06 |
---|---|
V-모델이 입력에 대한 값 변경을 수신하지 않음(vuejs) (0) | 2022.05.06 |
Axios를 사용하여 객체를 JSon으로 게시 (0) | 2022.05.06 |
Java에서 목록을 배열로 변환 (0) | 2022.05.06 |
인터페이스와 추상 클래스의 차이를 어떻게 설명해야 하는가? (0) | 2022.05.06 |