2012-02-26 3 views
0

원격 저장소 (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 바이트입니다 (큰 크기는이 현상에 아무런 영향을 미치지 않습니다).

어떤 아이디어가이 문제의 원인 일 수 있으며이 문제를 해결할 수있는 방법은 무엇입니까?

답변

1

... 클라이언트 서버가 두 연결에서 모두 32KiB 쓰기 명령 (예 : 4 연속 데이터 패킷)을 보내는 동안

테스트 설정에 대한 세부 정보를 제공 할 수 있습니까? 클라이언트가 두 연결에 패킷을 순차적으로 보내고 있습니까? 그러면 설정에 따라 클라이언트가 증가 할 수 있습니다.

로컬 호스트 설정 (한 대의 컴퓨터에서 클라이언트와 서버)입니까 아니면 다른 호스트의 클라이언트와 서버입니까? 둘 다 시험 했니? 특히 하나의 CPU 만 있고 테스트 클라이언트가 로컬로 실행되거나 심지어는 단일 스레드로 실행되는 경우 로컬 호스트 설정에서 실행 시간이 증가하는 것을 보지 마십시오.

+0

클라이언트와 서버가 유휴 코어가 많은 다른 시스템에서 실행 중입니다. 하지만 당신 말이 맞아요, 잘못은 클라이언트 측에있는 것 같습니다. 처음에는 테스트 소프트웨어의 품질에 대한 믿음이 너무 많았고 예비 측정 중에 버전이 바뀌었기 때문에 처음에는 이것을 보지 못했습니다. Microsoft iSCSI 초 기자와 함께 [iometer] (http://www.iometer.org/)를 사용하고 있었는데이 중 하나는 연결된 대상/서버에 관계없이 큰 지연을 초래하는 것으로 보입니다. – andreas