원격 저장소 (iSCSI 대상) 용 Java 서버를 작성했습니다. 클라이언트는 데이터 페이로드를 전달하는 패킷 시퀀스를 전송하여 데이터를 쓸 수 있습니다. 이러한 패킷은 고정 길이 헤더 (48 바이트)와 가변 길이 데이터 세그먼트로 구성됩니다. 데이터 세그먼트의 길이는 헤더에 지정되며 고정 된 것으로 간주 될 수 있습니다 (8KiB).큰 ByteBuffers에 대해 별도의 SocketChannels 동시 읽기()가 발생했습니다.
데이터 패킷을 수신하는 것은 두 부분으로 이루어진 프로세스입니다. 우선 헤더는 48 바이트의 크기로 ByteBuffer에 읽혀집니다. 그 직후에 ByteBuffer.allocate (...)를 통해 두 번째 ByteBuffer가 생성됩니다. 이 두 번째 버퍼의 크기는 머리글에 지정된 데이터 세그먼트 길이와 일치합니다. 그런 다음 데이터 세그먼트는 SocketChannel.read (ByteBuffer) 메서드를 사용하여 두 번째 ByteBuffer로 읽습니다. 단순한 경우이 프로세스는 예상대로 작동합니다. 데이터 세그먼트가 커지고 시퀀스가 길어지면 IO 속도가 빨라집니다. "간단한 경우"는 블로킹 SocketChannel을 사용하여 패킷을 수신 (처리)하는 단일 스레드가 있음을 의미합니다. 그러나 자체 TCP 연결과 관련된 SocketChannel이있는 두 번째 스레드가 추가되면 SockerChannel.read (ByteBuffer) 실행 시간이 2.5ms 이상으로 늘어나고 클라이언트 서버는 32KiB 쓰기 명령 (즉 4 개의 연속 데이터 패킷)을 두 가지 모두에 보냅니다 사이. 이것은 8에서 10 팩터 증가한 것입니다.
이 단계에서 두 개의 스레드는 동일한 네트워크 인터페이스 카드 이외의 다른 리소스를 공유하지 않습니다. 각 SocketChannel의 읽기 버퍼 크기는 43690 바이트입니다 (큰 크기는이 현상에 아무런 영향을 미치지 않습니다).
어떤 아이디어가이 문제의 원인 일 수 있으며이 문제를 해결할 수있는 방법은 무엇입니까?
클라이언트와 서버가 유휴 코어가 많은 다른 시스템에서 실행 중입니다. 하지만 당신 말이 맞아요, 잘못은 클라이언트 측에있는 것 같습니다. 처음에는 테스트 소프트웨어의 품질에 대한 믿음이 너무 많았고 예비 측정 중에 버전이 바뀌었기 때문에 처음에는 이것을 보지 못했습니다. Microsoft iSCSI 초 기자와 함께 [iometer] (http://www.iometer.org/)를 사용하고 있었는데이 중 하나는 연결된 대상/서버에 관계없이 큰 지연을 초래하는 것으로 보입니다. – andreas