• 링 버퍼(Ring Buffer)는 원형 큐로 약간의 개량해서 사용
  • 링 버퍼는 가변적인 데이터를 처리
  • 기본적으로 네트워크의 처리 단위 : 1/1000 초
  • 기본적으로 CPU의 처리 단위 : 1/1000000 초 이하
  • 네트워크와 CPU는 처리 속도가 수 백에서 수 만 배 차이 발생
  • 네트워크의 통신에서 패킷의 크기가 고정되어 있으면 프로그램이 쉽지만 필요 없는 데이터까지 입/출력에 포함되어 있어서 네트워크의 성능을 떨어짐
  • 가변적인 크기를 가진 패킷을 사용하는데 가변 크기를 가진 패킷을 저장하기 위해 링 버퍼(Ring Buffer)라는 자료구조를 사용
  • 링 버퍼(Ring Buffer)는 분해된 패킷을 합치거나 완성되지 않은 자투리 패킷을 완전한 패킷으로 만들 수 있는데 편리
  • 링 버퍼(Ring Buffer)는 Byte 단위로 저장할 공간만 있으면 동작함.
  • FIFO 기반의 일반적인 선형 큐의 메모리가 꽉 차게되면 Overflow가 발생 하지만 링 버퍼(Ring Buffer)는 head와 tail이 붙어 있는 형태의 큐를 구성으로 dropped 되어 유실되는 packet을 방지 가능

Network Ring Buffer Size 설정

  • Ring Buffer는 네트워크 카드의 버퍼 공간
  • 스위치에서 서버로 전달된 패킷의 전달 과정
    1. 네트워크 카드 내 Ring Buffer 에 보관 (NIC 카드 → Ring Buffer)
    2. 커널의 Socket RCV Buffer로 이동 (Ring Buffer → Socket RCV Buffer)
    3. User Application의 read 함수를 통해 전달 (Socket RCV Buffer → Application의 read()가 값 읽음)
  • Kernel의 Socket RCV Buffer가 여유가 있더라도 Ring Buffer Size가 작다면 중간 병목(bottleneck)이 발생 → Ring Buffer는 가능하다면 Maximum 값으로 설정해주는 것이 권장
  • 리눅스에서는 패킷 송수신시 1계층 물리적 케이블을 통하여 NIC로 packet이 수신 되면 가장 먼저 Ring Buffer 라는 영역에 보관한 뒤에 처리

  • Linux 상에서 NIC의 Ring Buffer(Current, Maximum) 값은 ethtool -g 명령어를 통해 확인 가능
    1. eth1 maximum으로 처리 가능한 ring buffer size는 4096임
    2. eth1 Current으로 처리 가능한 ring buffer size는 512으로 설정
    3. 리눅스 상에서packet 의 drop 과 error 를 줄이기 위해서 maximum 과 Current 동일하게 설정하는 것이 좋음
      # interface의 경우 최대 값이 4,096이지만 현재 설정 값은 512
      $ ethtool -g em1
      Ring parameters for em1:
      Pre-set maximums:
      RX:             4096
      RX Mini:        0
      RX Jumbo:       0
      TX:             4096
      Current hardware settings:
      RX:             512
      RX Mini:        0
      RX Jumbo:       0
      TX:             512

  • ethtool -G 명령어에 해당 파라미터를 maximum 값과 동일하게 설정 한뒤 설정 값을 변경

    # ethtool -G 명령어를 통해 ring buffer를 최대 값으로 설정
    $ ethtool -G em1 rx 4096
    $ ethtool -G em1 tx 4096
    
    # 변경된 ring buffer 내용 확인
    $ ethtool -g em1
    Ring parameters for em1:
    Pre-set maximums:
    RX:             4096
    RX Mini:        0
    RX Jumbo:       0
    TX:             4096
    Current hardware settings:
    RX:             4096
    RX Mini:        0
    RX Jumbo:       0
    TX:             4096



Network Ring Buffer Size 확대 영구적으로 등록

  • 대부분의 Linux 설정과 같이 명령어는 현재 메모리 상의 값을 변경하기 때문에 재부팅 시에는 이전 값으로 원복됨
  • 영구적으로 변경하기 위해서는 Network script 내 해당 Interface에 관련 설정 값을 추가해주는 것이 필요
  • 아래와 같이 스크립트 파일 내 ETHTOOL_OPTS 옵션을 추가한 후 해당 설정 값을 입력 → rx/tx의 최대 값을 확인 후 작성 필요
    $ cat /etc/sysconfig/network-scripts/ifcfg-em1
    TYPE=Ethernet
    BOOTPROTO=static
    DEFROUTE=yes
    NAME=em1
    DEVICE=em1
    ONBOOT=yes
    IPADDR=1.255.156.21
    NETMASK=255.255.255.224
    GATEWAY=1.255.156.1
    ETHTOOL_OPTS="-G ${DEVICE} rx 4096 ; -G {$DEVICE} tx 4096"
  • 재부팅시에 Network Ring Buffer Size 확대 명령어 실행 → rc-local.service 사용
    $ vi /etc/rc.local
    # 아래의 값이 등록
    ethtool -G eth1 rx 4096
    ethtool -G eth1 tx 4096


※ 참고 사항 → rc-local.service를 실행하는 방법

# rc-local.service를 실행할 수 있는 환경 적용
$ echo -e "\n[Install]\nWantedBy=multi-user.target" >> /usr/lib/systemd/system/rc-local.service
$ chmod u+x /etc/rc.d/rc.local

 # rc-local.service 실행
/bin/systemctl daemon-reload
/bin/systemctl restart rc-local.service
/bin/systemctl enable rc-local.service

$ echo -e "rc-local.service가 rebooting에도 실행되는 지 확인"
/bin/systemctl list-unit-files | grep rc.local



※ 패킷 전송 및 수신 에 관련된 버퍼 참고 사항


+ Recent posts