1.
오래전 윈도우를 단순히 데스크탑으로 이용하지 말고 서버프로그램으로 이용해보자는 글을 썼습니다. 이와 연결된 글입니다.
2년전입니다. 어떤 분이 Solaris x.86을 이용하여 매매서버를 만들었습니다. Latency를 줄이기 위한 측정을 했지만 Jitter로 만족스러운 성능이 나오지 않았습니다. 이런 저런 시도끝에 jitter를 대폭 줄여서 만족스러운 성능을 얻었습니다. 무엇을 했을까요?
Solaris는 TCP/IP튜닝을 위한 아주 많은 커널패러매터를 제공합니다.
Internet Protocol Suite Tunable Parameters
이중에서 두가지 패러매터를 수정하였습니다. tcp_naglim_def와 tcp_deferred_acks_max입니다. 위의 자료에서 각각을 찾으면 다음과 같은 역할을 합니다.
tcp_deferred_acks_max:Specifies the maximum number of TCP segments received from remote destinations (not directly connected) before an acknowledgment (ACK) is generated. TCP segments are measured in units of maximum segment size (MSS) for individual connections. If set to 0 or 1, no ACKs are delayed, assuming all segments are 1 MSS long. The actual number is dynamically calculated for each connection. The value is the default maximum.
tcp_naglim_def:This parameter controls the Nagle algorithm threshold. TCP uses the minimum of this parameter and the MSS of a connection to determine when the Nagle algorithm should kick in. For example, if the amount of new data is more than 1 MSS, the data is sent out regardless of the value of this parameter. If this parameter is set to 1, the Nagle is disabled for all TCP connections
1 2 |
ndd -set /dev/tcp tcp_naglim_def 1 ndd -set /dev/tcp tcp_deferred_acks_max 0 |
그러면 Linux는 어떨까요? IBM이 제공하는 자료는 아래와 같은 방안을 제시하고 있습니다.
The first thing you should consider is that the Nagle algorithm fulfills a need. Because the algorithm coalesces data to try to fill a complete TCP packet segment, it does introduce some latency. But it does this with the benefit of minimizing the number of packets sent on the wire, and so it minimizes congestion on the network. But in cases where you need to minimize that transmit latency, the Sockets API provides a solution. To disable the Nagle algorithm, you can set the TCP_NODELAY socket option, as shown in Listing 1.
Boost socket performance on Linux중에서
Linux에 있어서의 소켓 기능의 향상을 보시면 번역한 글을 읽을 수 있습니다.
1 2 3 4 5 6 7 8 9 10 11 12 |
int sock, flag, ret; /* Create new stream socket */ sock = socket( AF_INET, SOCK_STREAM, 0 ); /* Disable the Nagle (TCP No Delay) algorithm */ flag = 1; ret = setsockopt( sock, IPPROTO_TCP, TCP_NODELAY, (char *)&flag, sizeof(flag) ); if (ret == -1) { printf("Couldn't setsockopt(TCP_NODELAY)\n"); exit( EXIT_FAILURE ); } |
Solaris는 tcp_naglim_def값을 변경하는 방식이지만 Linux는 Socket Option으로 TCP_NODELAY를 사용합니다. 그러면 Solaris의 tcp_deferred_acks_max와 같은 역할을 하는 것은 있을까요? 찾아보니까 시험판이지만 아래와 같은 항목을 지원한다고 합니다. 아직 시험판입니다.
/proc/sys/net/ipv4/tcp_default_delack_segs, represents the threshold for the number of segments.
/proc/sys/net/ipv4/tcp_default_delack_min, specifies the minimum timeout value
/proc/sys/net/ipv4/tcp_default_delack_max, specifies the maximum timeout value.In addition, new TCP socket options are added to allow per-socket configuration:
TCP_DELACK_SEGS
TCP_DELACK_MIN
TCP_DELACK_MAX
TCP: Support configurable delayed-ack parameters중에서
2.
이렇게 긴 서론을 한 이유가 있습니다. 요즘 ELW시장이 다시 활기를 찾고 있다는 기사가 있었습니다.
DMA방식으로 ELW 트레이딩을 하는 분들의 경우 윈도우를 이용하여 서버를 구축한 경우가 많습니다. 대부분 windows 7 혹 적지만 Windows 2008 서버를 사용하신다고 합니다. 요즘 여의도에서 ELW슈퍼메뚜기로 활약하시는 팀이 있다고 합니다. 알고보니 아는 분이더군요. 다른 분을 통해 들었더니 Windows 8과 Windows 2012서버가 지원하는 Winsock Extension을 사용한다고 합니다. Windows 7 계열의 winsock보다 20~30% 더 좋은 성능을 제공하는 RIO, Regitered I/O입니다.
Winsock(Windows 소켓)의 새로운 확장인 RIO API는 네트워크 대기 시간을 줄이고, 메시지 속도를 높이며, 매우 높은 성능과 메시지 속도 및 예측성이 필요한 응용 프로그램의 응답 시간 예측성을 개선합니다. 작은 메시지를 많이 처리하는 응용 프로그램은 RIO API 확장을 통해 지터 및 대기 시간은 줄이고 IOPS(초당 I/O 작업)는 늘릴 수 있습니다. 메시지 속도가 높고 대기 시간이 짧은 서버 부하가 금융 서비스 거래 및 고속 시장 데이터 수신/유포용 응용 프로그램 등의 RIO API 확장을 사용하면 가장 큰 이점을 얻을 수 있습니다. 또한 RIO API 확장은 물리적 컴퓨터 한 대에 여러 Hyper-V VM(가상 컴퓨터)을 배포할 때 높은 IOPS를 제공합니다. RIO로 요청 및 완료 시 큐를 사용하여 미리 등록된 버퍼로 보내기/받기 작업을 수행할 수 있습니다. 보내기/받기 작업은 Winsock 소켓에 연결된 요청 큐에 저장됩니다. 완료된 I/O 작업이 완료 큐에 삽입되어 서로 다른 여러 소켓을 같은 완료 큐에 연결할 수 있습니다. 완료 큐를 보내기 완료와 받기 완료로 구분할 수도 있습니다. 폴링과 같은 완료된 작업의 경우 시스템을 호출하지 않고 전적으로 사용자 모드에서 수행할 수 있습니다.
등록된 버퍼를 사용하면 네트워크 관련 처리가 간소화되고 지터가 감소할 뿐만 아니라, 응용 프로그램 개발자가 프로토콜 스택에서 사용되는 네트워킹 버퍼의 NUMA 노드 선호도를 지정할 수 있으므로 전체적인 성능이 더욱 향상되며 대기 시간 및 지터 특성이 감소합니다.RIO API 확장은 TCP(Control Protocol), UDP(User Datagram Protocol) 및 멀티캐스트 UDP와 IPv4/IPv6을 모두 지원합니다.
다음과 같은 경우 RIO API 확장을 사용할 수 있습니다.
메시지당 CPU 사용률을 최소화하기 위해 서버를 수직 확장하려는 경우
네트워킹 스택에 대한 대기 시간의 영향 및 지터를 최소한으로 줄이려는 경우
매우 속도가 빠른 멀티캐스트 또는 UDP 트래픽을 처리하는 경우
RIO(등록된 입/출력) API 확장중에서
윈도우간의 레이턴시경쟁, 윈도우를 OS로 사용하는 DMA트레이더간의 경쟁에서 이기기 위하여 좀더 좋은 성능을 내는 Regitered I/O를 기반으로 매매프로그램을 설계한 듯 합니다. RIO는 특정한 트레이더만이 가진 기술이 아닙니다. 마이크로소프트가 상품으로 판매하는 제품에 있는 기술이면 이를 선택하는 것은 전적으로 트레이더입니다. 혹 Windows 7기반의 Winsock2라고 하면 바꾸어 시험해보실 의향이 있으신가요?
3.
비록 관심을 가지고 보는 것은 아니지만 윈도우가 지원하는 다양한 Low Latency 기술을 살펴보도록 하죠.
Linux의 경우 TCP Offload Engine이라는 기술입니다. 이에 대응하는 윈도우 기술은 TCP Chimney입니다. 마이크로소프트는 “TCP Chimney 오프로드는 네트워크를 통한 데이터 이동 관련 작업을 호스트 컴퓨터의 CPU에서 네트워크 어댑터로 오프로드할 수 있게 해주는 네트워킹 기술입니다. 이 기술을 사용하면 관리 효율성이나 보안에 손실을 주거나 추가 프로그램 사용하지 않고도 컴퓨터 또는 서버의 네트워크 데이터 처리 작업을 향상시킬 수 있습니다”라고 정의합니다.
다음은 NetDMA=Network Direct Memory Access로 RDMA기술입니다.
The NetDMA interface provides offloading of direct memory access (DMA) to network interface cards (NICs) that support a NetDMA DMA engine. The Windows Server 2008 and Windows Vista with Service Pack 1 (SP1) operating systems add NetDMA versions 1.1 and 2.0. NDIS 6.1 drivers can use NetDMA version 1.0, 1.1, and 2.0 interfaces. These interfaces manage interactions with the DMA engine and manage DMA transfers at run-time. The NetDMA interface is an optional service that is provided for NICs and other drivers.
NetDMA를 지원하는 카드를 사용하고 NetDMA가 가능하도록 설정을 하면 RDMA Application을 개발하여야 합니다. 이 때 사용하여야 하는 Interface가 Network Direct Interface입니다. Linux의 경우 Verb로 말하는 것과 같은 듯 합니다.
Windows HPC Server 2008 introduces a new low-latency RDMA network API known as “Network Direct”. This RDMA interface in addition to and distinct from the existing “Winsock Direct” interface. The Network Direct interface introduces several advantages over Winsock Direct including no dependency on the Winsock stack and much lower latency metrics. MS MPI is being developed to take advantage of this new interface. This means that Infiniband vendors, for instance, will need to provide HCA Network Direct providers in addition to (or perhaps instead of) the Winsock Direct providers published previously. Consequently, development is underway by both Microsoft and partners to enable full support for the entire network stack. For programmers, the Network Direct API provides a model similar to the User Mode Driver Framework (UMDF). MS MPI will be the first user-mode application to leverage Network Direct.
New Network Direct RDMA Interface Available with Windows Server 2008중에서
TCP Chimney Offload overview 을 보시면 TCP Chimney와 NetDMA를 잘 설명하고 있습니다.
너무나 익숙하지 않은 윈도우의 마지막 기술입니다.kRDMA입니다. Windows 8부터 지원하는 기술입니다. NetDMA를 설명하는 글속에 “NetDMA is not supported in Windows 8 and later versions of the Windows operating system.”라는 문장이 있는 것으로 보아 NetDMA가 kRDMA로 바뀐 듯 합니다. 마이크로소프트의 설명입니다.
kRDMA is a new feature for Windows Server 2012. Kernel mode Remote Direct Memory Access (RDMA) is an accelerated input-output (I/O) delivery model that allows application software to bypass most software layers to communicate directly with the computer hardware, which improves application performance and reduces delay.
마지막으로 처음 질문으로 돌아가죠. Linux와 Solaris를 알아보았습니다. 그러면 윈도우는 어떻게 해야 할까요? 아래 두가지 패러매터값을 조정하시면 됩니다.
TCPAckFrequency “uses delayed acknowledgments to reduce the number of packets that are sent on the media”. Instead of sending an acknowledgment each time, acknowledgments are delayed.
TCPNoDelay determines whether nagling is enabled or disabled. Nagling “is a feature that combines several packets into a single, larger packet for more efficient transmissions”.
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\MSMQ\Parameters 에서 DWORD값 TCPNoDelay 생성 16진수 값 1 지정d을 하고 HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters\Interfaces 안의 폴더중에서아이피주소가 적혀있는 폴더에 DWORD값 TcpAckFrequency 생성 16진수 값 1로 지정하면 됩니다.
혹 제가 틀린 점이 있으면 꼭 지적해주세요. 워낙 익숙하지 않은 윈도우 기술이라 글을 쓴 저도 머리가 아픕니다.고수의 친절한 댓글을 기대합니다.(^^)