• python2에서 ftplib 라이브러리 사용법 참조 가능
  • domain_list.txt 파일은 확인하고 싶은 도메인 리스트
  • python2.6으로 ftp 활용하여 특정 디렉토리에 파일 다운로드 코드 예제

    $ vi /root/ftp_file.py
    #!/bin/python2.6
    from ftplib import FTP
    import os
    from datetime import date, timedelta
    
    def file_read_line():
        read_file = []
        f = open(os.path.abspath(os.getcwd()) + '/domain_list.txt', 'r')
        while True:
            line = f.readline().strip()
            if not line:
                break
            read_file.append(line)
        f.close()
        return read_file
    
    def get_list_ftp(ftp, now_pwd, all_list=[]):
        datas = []
    
        try:
            dir_exist = ftp.cwd(now_pwd)
            data_list = ftp.nlst()
    
            for index, data_name in enumerate(data_list):
                if data_name =='.' or data_name == '..':
                    continue
                datas.append(now_pwd+data_name)
            return datas, dir_exist.split(' ')[0]
        except:
            return datas, '500'
    
    def download_path(dir_name):
        test_dir = '/' + dir_name
        if os.path.isdir(test_dir) is False:
            os.makedirs(test_dir)
        return test_dir
    
    def download_files(ftp, down_file, download_path):
        for file in down_file:
            file_name = (file.split('/')[-1])
            path_name = file.replace(file_name, '')
            ftp.cwd(path_name)
            try:
                ftp.retrbinary("RETR %s" % file_name, open(download_path+'/'+file_name,'wb').write)
            except Exception:
                print down_load_path, "/", file_name, "is downloaded failed"
    
    if __name__=="__main__":
        ftp = FTP('FTP 접속 IP')
        ftp.login('FTP ID','FTP PW')
    
        ftp.encoding='cp949'
        #print ftp.getwelcome()
    
        domains  = file_read_line()
        for domain in domains:
            all_list, down_status = get_list_ftp(ftp,'/'+domain+'/')
            if down_status != '250':
                print '/'+domain+'/ director is not exist'
                continue
            down_dir = download_path(domain)
    
            #file download
            download_files(ftp, all_list, down_dir)
    
        # ftp connect close
        ftp.quit()

  • FTP 서버에서 다운받을 디렉토리 리스트

    • a와 같이 FTP 서버에 존재하지 않는 디렉토리는 다운로드에 제외
    • 도메인을 추가하려면 마지막 줄에 추가하면 됨
      $ cat /root/domain_list.txt
      google.com
      a                             # 오류발생함으로 원래는 삭제되지만, 테스트를 위해서 투입
      baidu.com

  • FTP 추출 python2.6 스크립트 실행

    $ python2 /root/ftp_file.py

Update-alternatives로 파이썬 버전 등록 및 변경

  • 파이썬 버전 수정하기 전에 이미 등록된 것이 있는지 확인 필요
  • update-alternatives --config python 을 입력하였을 때 아무 값도 나오지 않으면 아무것도 등록된 것이 없다는 의미
    $ update-alternatives --config python

  • update-alternatives --install [symbolic link path] python [real path] number 명령어는 실행파일을 등록하는 명령어

  • 아래의 명령어 3개를 입력하면 2.7 버전과 3.6버전, 3.7버전이 update-alternatives에 등록

  • 파이썬 2.7과 3.6, 3.7이 설치되어 있어야만 update-alternatives에 등록이 가능

  • python의 설치 위치가 아래의 명령어와 다르다면 path를 변경해야만 실행이 가능

    $ update-alternatives --install /bin/python python /bin/python2.7 1
    $ update-alternatives --install /bin/python python /bin/python3.6 2
    $ update-alternatives --install /bin/python python /bin/python3.7 3

  • update-alternatives에 등록한 후 update-alternatives --config python 명령어를 입력하면 등록한 파이썬 버전을 선택하는 메뉴가 출력

    $ update-alternatives --config python
    
    There are 3 programs which provide 'python'.
    
      Selection    Command
    -----------------------------------------------
         1           /bin/python2.7
         2           /bin/python3.6
    *+ 3           /bin/python3.7
    
    Enter to keep the current selection[+], or type selection number:

  • 원하는 메뉴의 번호를 입력한 후 파이썬 버전을 확인하면 파이썬 버전을 확인 가능 → 3을 입력

  • 파이썬의 link를 따라가보면 alternatives 명령어로 설정 → alternatives가 /bin/python3.7을 가리킴

    # 선정된 python의 소프트링크 확인
    $ ls -al /bin/python
    lrwxrwxrwx 1 root root 24 Jan 18 23:50 /bin/python -> /etc/alternatives/python
    
    $ python -V
    Python 3.7.3



python3 업데이트 후 YUM 실행 시 SyntaxError: invalid syntax 에러

  • CentOS 7을 사용하던 도중에 파이썬(Python)을 2.7에서 3.7 버전으로 업그레이드를 할 필요有

  • 파이썬 3.7.3 버전을 설치한 후 /usr/bin에 있던 python 링크 또한 2.7에서 3.7 버전으로 변경

  • 아래와 같이 명령어를 실행하면 현재 파이썬 버전이 3.7이라는 것을 확인 가능

    $ python -V
    Python 3.7.3

  • 문제 발생(거의 항상 발생) → 파이썬을 3.7로 교체한 후 yum이 실행 X

    $ yum update
    File "/usr/bin/yum", line 30
      except KeyboardInterrupt, e:
                              ^
    SyntaxError: invalid syntax

  • yum이 파이썬 2.7 버전을 사용하고 있었는데 파이썬을 3.7으로 업데이트하면서 문법적 문제가 발생

  • 해결방법은 간단 → yum을 파이썬 2.7 버전에서 실행되도록 수정만 하면 됨

  • /usr/bin/yum 스크립트 내용 확인

    $ cat /usr/bin/yum
    #!/usr/bin/python
    import sys
    try:
       import yum
    except ImportError:
       print >> sys.stderr, """\
    There was a problem importing one of the Python modules
    required to run yum. The error leading to this problem was:
    
      %s
    
    Please install a package which provides this module, or
    verify that the module is installed correctly.
    
    It's possible that the above module doesn't match the
    current version of Python, which is:
    %s
    
    If you cannot solve this problem yourself, please go to
    the yum faq at:
     http://yum.baseurl.org/wiki/Faq
    
    """ % (sys.exc_value, sys.version)
       sys.exit(1)
    
    sys.path.insert(0, '/usr/share/yum-cli')
    try:
       import yummain
       yummain.user_main(sys.argv[1:], exit_code=True)
    except KeyboardInterrupt, e:
       print >> sys.stderr, "\n\nExiting on user cancel."
       sys.exit(1)

  • 가장 첫 줄 #!/usr/bin/python을 통해 python 명령어가 실행됨을 확인 가능

  • python 명령어에 대한 링크를 python3.6으로 변경해 놓았기 때문에 yum이 파이썬 3.6 환경으로 실행된 것

  • /usr/bin/yum 파일은 python2로 설정되어있기에 가장 첫 줄을 "#!/usr/bin/python2"로 변경 필요

  • vi 에디터를 이용해서 첫 번째 줄을 아래와 같이 변경

    $ vi /usr/bin/yum
    #!/usr/bin/python2
    [...아래 내용 생략]

  • /usr/bin/yum 파일 변경 이후 추가로 /usr/libexec/urlgrabber-ext-down 파일 변경 필요

  • 파이썬 2.7 버전에서 실행될 수 있도록 가장 첫 줄 #!/usr/bin/python2 변경

    $ vi /usr/libexec/urlgrabber-ext-down
    #!/usr/bin/python2
    [...아래 내용 생략]

  • yum 명령을 실행 테스트 → 정상적으로 동작

    $ yum update -y
    Loaded plugins: fastestmirror
    Loading mirror speeds from cached hostfile
    * base: mirror.kakao.com
    * epel: ftp.iij.ad.jp
    * extras: mirror.kakao.com
    * updates: mirror.navercorp.com
    Resolving Dependencies
    --> Running transaction check
    ---> Package bind-export-libs.x86_64 32:9.11.4-26.P2.el7_9.2 will be updated
    ---> Package bind-export-libs.x86_64 32:9.11.4-26.P2.el7_9.3 will be an update



변경한 python을 사용할 때 오류 발생

  • 파이썬에서 다음과 같은 오류(ERROR: Python headers are missing in /usr/include/python3.6m)가 발생하면 python3-dev를 통해 문제를 해결
    $ yum install python3-dev

  • tx, rx 값을 1초마다 출력 → 소수 둘째자리까지 출력
  • 1초마다 나타나는 tx와 rx데이터를 그래프로 출력 필요 → 그래프 사용 용도에 대한 고민은 필요
  • 데이터 분석에 사용하기 위한 기초 자료로 사용 예정
  • tx, rx 값 뿐만아니라 CPU, MEMORY, DISK 등도 확장 가능
  • 1초간 tx, rx 확인하는 python3 예제 코드

    #! /bin/python3
    #-*- coding: utf-8 -*-
    from subprocess import Popen
    from subprocess import os
    from subprocess import PIPE
    from datetime import datetime
    import time
    from os import sys
    import signal
    
    def common_cmd(command, args):
        cmd = command + args
          p = Popen(cmd, shell=True, stdout=PIPE)
           (ret, err) = p.communicate()
           return ret
    
    def ifconfig_cmd():
        cmd_args = "| grep 'UP mode' | awk -F ':' '{print $2}'"
        ifconfig_ports = common_cmd('ip link ', cmd_args)
        ifconfig_ports = ifconfig_ports.decode()
        return ifconfig_ports
    
    def rx_cal():
        rx_cat_cmd_args = '/sys/class/net/'
        rx_cat_cmd_args = rx_cat_cmd_args + NIC_PORT +'/statistics/rx_bytes'
        rx_bs = common_cmd('cat ', rx_cat_cmd_args)
        rx_bs = rx_bs.decode()
        return rx_bs
    
    def tx_cal():
        tx_cat_cmd_args = '/sys/class/net/'
        tx_cat_cmd_args = tx_cat_cmd_args + NIC_PORT +'/statistics/tx_bytes'
        tx_bs = common_cmd('cat ', tx_cat_cmd_args)
        tx_bs = tx_bs.decode()
        return tx_bs
    
    def handler(signum, frame):
        print("\n"+"*" * 50 + "CTRL+Z" + "*" * 50)
        print_condition(max_rx, max_tx)
        sys.exit()
    
    def print_ms(rx_max, tx_max):
        now = str(datetime.now())
        now = now.split('.')[0]
        print("%s -> rx : %.2f MB/s\t\t\t\t\t tx : %.2f MB/s" %(now, rx_max, tx_max))
    
    def print_gs(rx_max, tx_max):
        now = str(datetime.now())
        now = now.split('.')[0]
        print("%s -> rx : %.2f GB/s\t\t\t\t\t tx : %.2f GB/s" %(now, rx_max, tx_max))
    
    def print_rx_gs(rx_max, tx_max):
        now = str(datetime.now())
        now = now.split('.')[0]
        print("%s -> rx : %.2f GB/s\t\t\t\t\t tx : %.2f MB/s" %(now, rx_max, tx_max))
    
    def print_tx_gs(rx_max, tx_max):
        now = str(datetime.now())
        now = now.split('.')[0]
        print("%s -> rx : %.2f MB/s\t\t\t\t\t tx : %.2f GB/s" %(now, rx_max, tx_max))
    
    def print_condition(max_rx, max_tx):
        if ((max_rx/1024) >=1):
            if ((max_tx/1024) >=1):
                g_rx_max = max_rx / 1024
                g_tx_max = max_tx / 1024
                print_gs(g_rx_max, g_tx_max)
            else:
                g_rx_max = max_rx / 1024
                print_rx_gs(g_rx_max, max_tx)
        else:
            if ((max_tx/1024) >=1):
                g_tx_max = max_tx / 1024
                print_tx_gs(max_rx, g_tx_max)
            else:
                print_ms(max_rx, max_tx)
    
    def byte_sum(lists):
        sum = lists[0] + lists[1] + lists[2] + lists[3] + lists[4] + lists[5] + lists[6] + lists[7]
        return sum
    
    if __name__ == "__main__":
        port_list = []
        ports = ifconfig_cmd()
        port_list = ports.split('\n')
        for index, value in enumerate(port_list):
            if (value != port_list[len(port_list)-1]):
                print("[%i] : %s\t" % (index, value), end = '')
        print("[99] : exit\n", end = '')
        print("\n위에 있는 NIC 포트는 사용 중인 것입니다.")
        try:
            NIC_PORT = input("원하는nic 포트를 입력하세요 : ")
            if (NIC_PORT == "exit" or NIC_PORT == "99"):
                exit()
            max_rx = 0
            max_tx = 0
            print("1초 간격으로 출력하겠습니다.")
    
            while True:
                rx_bs1 = rx_cal()
                tx_bs1 = tx_cal()
    
                time.sleep(1)
    
                rx_bs2 = rx_cal()
                tx_bs2 = tx_cal()
    
                rx_bs = int(rx_bs2) - int(rx_bs1)
                tx_bs = int(tx_bs2) - int(tx_bs1)
    
                rx_ms = float((rx_bs /1024 / 1024))
                tx_ms = float((tx_bs /1024 / 1024))
    
                rx_max = rx_ms * 8
                tx_max = tx_ms * 8
    
                print_condition(rx_max, tx_max)
    
                if (rx_max > max_rx):
                    max_rx = rx_max
    
                if (tx_max > max_tx):
                    max_tx = tx_max
    
                signal.signal(signal.SIGTSTP, handler)
    
        except KeyboardInterrupt:
            print("\n"+"*" * 50 + "CTRL+C" + "*" * 50)
            print_condition(max_rx, max_tx)
            # 종료
            sys.exit()

  • 1초간 tx, rx 확인하는 python3 실행 결과


  • 특수문자 %20는 공백(스페이스), 즉 "빈 칸"을 의미

  • 인터넷 주소에서는 원칙적으로 빈 칸이 들어갈 수 없음

  • 빈 칸(공백)은 하나의 글자 → 공백문자의 아스키 코드(ASCII Code)는 10진수로는 32, 16진수로는 20임

  • ASCII Code의 20를 활용하여 빈 칸을 인터넷 주소에서 %20으로 사용


  • 아래처럼 빈칸이 있는 경우 호출 불가

    http://www.baidu.com/Hello Test.html

  • 빈칸이 있는 주소에서 빈 칸을 %20 으로 변환하는 경우 호출 가능

    http://www.baidu.com/Hello%20Test.html

  • 리눅스 디스크 속도 측정, 리눅스 cpu 속도 확인, 리눅스 메모리 속도 측정에 사용될 수 있는 명령어
  • sysbench 명령어는 인텐시브한 로드에서 데이터베이스를 운영해야하는 시스템에 필요한 운영체제를 평가하는 모듈화된 크로스 플랫폼 멀티 쓰레드 벤치마크 도구
  • 데이터베이스를 설치하지 않고도 복잡한 세팅없이 시스템 성능을 분석 가능
  • VPS(virtual private server)를 사용하는 경우 업체에서 하드웨어 사양을 정확하게 명시하지는 않기 때문에 성능을 비교하는 데이터로도 활용 가능


sysbench 제공 기능

  • 파일 입출력 성능
  • 스케쥴러 성능
  • 메모리 할당 및 전달 속도
  • POSIX 쓰레드 구현 성능
  • 데이터베이스 서버 성능


sysbench 설치

$ yum install -y sysbench



sysbench 명령어 3가지 부분

  • 명령어 구분
    1. prepare → 테스트 데이터를 생성하는 과정
    2. run → 실제 테스트를 실행 (oltp-read-write, oltp-read-only 등)
    3. cleanup → 테스트 데이터를 삭제하는 과정


성능테스트 실행

  • "준비 -> 실행 -> 삭제" 순서로 진행


컴파일된 테스트 속성

  1. fileio → 파일 I/O 테스트
  2. cpu → CPU 성능 테스트
  3. memory→ 메모리 기능 속도 테스트
  4. threads→ 스레드 하위 시스템 성능 테스트
  5. mutex → 뮤텍스 성능 테스트


sysbench 명령어 테스트

1. CPU 테스트 → total time이 낮을 수록 좋음

  • 소수 생성을 100000개 하여 cpu 테스트(기본적)

    $ sysbench --test=cpu --cpu-max-prime=100000 run
    WARNING: the --test option is deprecated. You can pass a script name or path on the command line without any options.
    sysbench 1.0.17 (using system LuaJIT 2.0.4)
    
    Running the test with following options:
    Number of threads: 1
    Initializing random number generator from current time
    
    Prime numbers limit: 100000
    
    Initializing worker threads...
    
    Threads started!
    
    CPU speed:
      events per second:    42.93
    
    General statistics:
      total time:                          10.0109s
      total number of events:              430
    
    Latency (ms):
           min:                                   22.98
           avg:                                   23.28
           max:                                   65.15
           95th percentile:                       23.10
           sum:                                10010.21
    
    Threads fairness:
      events (avg/stddev):           430.0000/0.00
      execution time (avg/stddev):   10.0102/0.00

  • CPU 코어 수에 맞춰 cpu 테스트 → 하이퍼 스레드를 적용하고 있다면 코어 수에 x2를 하여 --cpu-max-prime 값을 적용

    # CPU 코어 확인
    $ lscpu  | grep -i "^CPU(s)"
    CPU(s):                40
    
    # CPU 코어 40개 활용하여 테스트
    $ sysbench --test=cpu --cpu-max-prime=100000 --num-threads=40 run
    WARNING: the --test option is deprecated. You can pass a script name or path on the command line without any options.
    WARNING: --num-threads is deprecated, use --threads instead
    sysbench 1.0.17 (using system LuaJIT 2.0.4)
    
    Running the test with following options:
    Number of threads: 40
    Initializing random number generator from current time
    
    Prime numbers limit: 100000
    
    Initializing worker threads...
    
    Threads started!
    
    CPU speed:
      events per second:  1256.42
    
    General statistics:
      total time:                          10.0281s
      total number of events:              12602
    
    Latency (ms):
           min:                                   27.73
           avg:                                   31.75
           max:                                   75.39
           95th percentile:                       31.37
           sum:                               400126.02
    
    Threads fairness:
      events (avg/stddev):           315.0500/2.31
      execution time (avg/stddev):   10.0032/0.02



2. Memory 테스트 → Read + Write = total이 높을 수록 좋음

  • 현재 설정된 메모리 기본값 검사 → 메모리 테스트의 기본값은 쓰기이므로 쓰기 테스트 값이 나옴

    $ sysbench --test=memory run
    WARNING: the --test option is deprecated. You can pass a script name or path on the command line without any options.
    sysbench 1.0.17 (using system LuaJIT 2.0.4)
    
    Running the test with following options:
    Number of threads: 1
    Initializing random number generator from current time
    
    Running memory speed test with the following options:
    block size: 1KiB
    total size: 102400MiB
    operation: write
    scope: global
    
    Initializing worker threads...
    
    Threads started!
    
    Total operations: 46492508 (4646316.29 per second)
    
    45402.84 MiB transferred (4537.42 MiB/sec)
    
    General statistics:
      total time:                          10.0002s
      total number of events:              46492508
    
    Latency (ms):
           min:                                    0.00
           avg:                                    0.00
           max:                                    0.02
           95th percentile:                        0.00
           sum:                                 4387.09
    
    Threads fairness:
      events (avg/stddev):           46492508.0000/0.00
      execution time (avg/stddev):   4.3871/0.00

  • 메모리 write 테스트(설정 有)

    1. memory block size는 1K

    2. 전역 메모리 사용

    3. 메모리 전체 사이즈는 128G

    4. write 테스트

      $ sysbench --test=memory --memory-block-size=1K --memory-scope=global --memory-total-size=128G --memory-oper=write run
      WARNING: the --test option is deprecated. You can pass a script name or path on the command line without any options.
      sysbench 1.0.17 (using system LuaJIT 2.0.4)
      
      Running the test with following options:
      Number of threads: 1
      Initializing random number generator from current time
      
      Running memory speed test with the following options:
      block size: 1KiB
      total size: 131072MiB
      operation: write
      scope: global
      
      Initializing worker threads...
      
      Threads started!
      
      Total operations: 46494366 (4646521.96 per second)
      
      45404.65 MiB transferred (4537.62 MiB/sec)
      
      General statistics:
      total time:                          10.0002s
      total number of events:              46494366
      
      Latency (ms):
       min:                                    0.00
       avg:                                    0.00
       max:                                    0.10
       95th percentile:                        0.00
       sum:                                 4385.85
      
      Threads fairness:
      events (avg/stddev):           46494366.0000/0.00
      execution time (avg/stddev):   4.3859/0.00

  • 메모리 write 테스트(설정 有)

    1. memory block size는 1K

    2. 전역 메모리 사용

    3. 메모리 전체 사이즈는 128G

    4. read 테스트

      $ sysbench --test=memory --memory-block-size=1K --memory-scope=global --memory-total-size=128G --memory-oper=read run
      WARNING: the --test option is deprecated. You can pass a script name or path on the command line without any options.
      sysbench 1.0.17 (using system LuaJIT 2.0.4)
      
      Running the test with following options:
      Number of threads: 1
      Initializing random number generator from current time 
      
      Running memory speed test with the following options:
      block size: 1KiB
      total size: 131072MiB
      operation: read
      scope: global
      
      Initializing worker threads...
      
      Threads started!
      
      Total operations: 58485027 (5844890.88 per second)
      
      57114.28 MiB transferred (5707.90 MiB/sec)
      
      General statistics:
      total time:                          10.0002s
      total number of events:              58485027
      
      Latency (ms):
       min:                                    0.00
       avg:                                    0.00
       max:                                    0.09
       95th percentile:                        0.00
       sum:                                 2841.56
      
      Threads fairness:
      events (avg/stddev):           58485027.0000/0.00
      execution time (avg/stddev):   2.8416/0.00



3. Disk 테스트 → 결과 값이 높을 수록 좋음

  • 리눅스는 기본적으로 Disk 캐시가 정용되어 있기 때문에 현재 장착된 RAM 크기보다 큰 값을 옵션으로 넣어야 함
  • 리눅스 Disk 속도를 측정하기 위해서는 테스트 파일을 준비
  • 테스트 파일을 Disk에 저장하고 테스트를 진행
  • 테스트용 더미 파일을 준비 → 전체 용량이 350G 파일을 준비

    1. 지정한 파일 크기를 128개로 나눠 생성

    2. 마지막 라인에 초당 생성한 파일 용량이 표시

      $ sysbench --test=fileio --file-total-size=350G prepare
      WARNING: the --test option is deprecated. You can pass a script name or path on the command line without any options.
      sysbench 1.0.17 (using system LuaJIT 2.0.4)
      
      128 files, 2867200Kb each, 358400Mb total
      Creating files for the test...
      Extra file open flags: (none)
      Creating file test_file.0
      Creating file test_file.1
      Creating file test_file.2
      Creating file test_file.3
      Creating file test_file.4
      [...중략...]
      Creating file test_file.124
      Creating file test_file.125
      Creating file test_file.126
      Creating file test_file.127
      375809638400 bytes written in 2320.59 seconds (154.44 MiB/sec).
      
      # test_file.* 이름으로 파일이 생성 (2.8G 파일이 총 128개 생성)
      $ ls -alh test_file.*
      -rw------- 1 root root 2.8G Oct 13 11:07 test_file.0
      -rw------- 1 root root 2.8G Oct 13 11:07 test_file.1
      -rw------- 1 root root 2.8G Oct 13 11:09 test_file.10
      -rw------- 1 root root 2.8G Oct 13 11:38 test_file.100
      -rw------- 1 root root 2.8G Oct 13 11:38 test_file.101
      [...생략...]

  • 60초동안 순차 읽기 I/O (seqrd) → 테스트용 더미 파일에 문제가 있으면 다시 생성하여 테스트 필요

     $ sysbench --test=fileio --file-test-mode=seqrd --max-time=60 --file-total-size=350G run
     WARNING: the --test option is deprecated. You can pass a script name or path on the command line without any options.
     WARNING: --max-time is deprecated, use --time instead
     sysbench 1.0.17 (using system LuaJIT 2.0.4)
    
     Running the test with following options:
     Number of threads: 1
     Initializing random number generator from current time
    
     Extra file open flags: (none)
     128 files, 2.7344GiB each
     350GiB total file size
     Block size 16KiB
     Periodic FSYNC enabled, calling fsync() each 100 requests.
     Calling fsync() at the end of test, Enabled.
     Using synchronous I/O mode
     Doing sequential read test
     Initializing worker threads...
    
     Threads started!
    
     File operations:
         reads/s:                      8942.74
         writes/s:                     0.00
         fsyncs/s:                     0.00
    
     Throughput:
         read, MiB/s:                  139.73
         written, MiB/s:               0.00
    
     General statistics:
         total time:                          60.0005s
         total number of events:              536615
    
     Latency (ms):
              min:                                    0.00
              avg:                                    0.11
              max:                                  160.53
              95th percentile:                        0.57
              sum:                                59796.43
    
     Threads fairness:
         events (avg/stddev):           536615.0000/0.00
         execution time (avg/stddev):   59.7964/0.00

  • 60초동안 순차 쓰기 I/O (seqwr)

     $ sysbench --test=fileio --file-test-mode=seqwr --max-time=60 --file-total-size=350G run
     WARNING: the --test option is deprecated. You can pass a script name or path on the command line without any options.
     WARNING: --max-time is deprecated, use --time instead
     sysbench 1.0.17 (using system LuaJIT 2.0.4)
    
     Running the test with following options:
     Number of threads: 1
     Initializing random number generator from current time
    
     Extra file open flags: (none)
     128 files, 2.7344GiB each
     350GiB total file size
     Block size 16KiB
     Periodic FSYNC enabled, calling fsync() each 100 requests.
     Calling fsync() at the end of test, Enabled.
     Using synchronous I/O mode
     Doing sequential write (creation) test
     Initializing worker threads...
    
     Threads started!
    
     File operations:
         reads/s:                      0.00
         writes/s:                     13674.29
         fsyncs/s:                     17503.17
    
     Throughput:
         read, MiB/s:                  0.00
         written, MiB/s:               213.66
    
     General statistics:
         total time:                          60.0047s
         total number of events:              1870845
    
     Latency (ms):
              min:                                    0.00
              avg:                                    0.03
              max:                                  172.79
              95th percentile:                        0.03
              sum:                                59169.98
    
     Threads fairness:
         events (avg/stddev):           1870845.0000/0.00
         execution time (avg/stddev):   59.1700/0.00

  • 60초동안 순차 다시 쓰기 I/O (seqrewr)

     $ sysbench --test=fileio --file-test-mode=seqrewr --max-time=60 --file-total-size=350G run
     WARNING: the --test option is deprecated. You can pass a script name or path on the command line without any options.
     WARNING: --max-time is deprecated, use --time instead
     sysbench 1.0.17 (using system LuaJIT 2.0.4)
    
     Running the test with following options:
     Number of threads: 1
     Initializing random number generator from current time
    
     Extra file open flags: (none)
     128 files, 2.7344GiB each
     350GiB total file size
     Block size 16KiB
     Periodic FSYNC enabled, calling fsync() each 100 requests.
     Calling fsync() at the end of test, Enabled.
     Using synchronous I/O mode
     Doing sequential rewrite test
     Initializing worker threads...
    
     Threads started!
    
     File operations:
         reads/s:                      0.00
         writes/s:                     13543.70
         fsyncs/s:                     17337.94
    
     Throughput:
         read, MiB/s:                  0.00
         written, MiB/s:               211.62
    
     General statistics:
         total time:                          60.0008s
         total number of events:              1852962
    
     Latency (ms):
              min:                                    0.00
              avg:                                    0.03
              max:                                   38.39
              95th percentile:                        0.02
              sum:                                59021.35
    
     Threads fairness:
         events (avg/stddev):           1852962.0000/0.00
         execution time (avg/stddev):   59.0214/0.00

  • 60초동안 랜덤 읽기 I/O (rndrd) → 테스트용 더미 파일에 문제가 있으면 다시 생성하여 테스트 필요

     $ sysbench --test=fileio --file-test-mode=rndrd --max-time=60 --file-total-size=350G run
     WARNING: the --test option is deprecated. You can pass a script name or path on the command line without any options.
     WARNING: --max-time is deprecated, use --time instead
     sysbench 1.0.17 (using system LuaJIT 2.0.4)
    
     Running the test with following options:
     Number of threads: 1
     Initializing random number generator from current time
    
     Extra file open flags: (none)
     128 files, 2.7344GiB each
     350GiB total file size
     Block size 16KiB
     Number of IO requests: 0
     Read/Write ratio for combined random IO test: 1.50
     Periodic FSYNC enabled, calling fsync() each 100 requests.
     Calling fsync() at the end of test, Enabled.
     Using synchronous I/O mode
     Doing random read test
     Initializing worker threads...
    
     Threads started!
    
     File operations:
         reads/s:                      287.78
         writes/s:                     0.00
         fsyncs/s:                     0.00
    
     Throughput:
         read, MiB/s:                  4.50
         written, MiB/s:               0.00
    
     General statistics:
         total time:                          60.0024s
         total number of events:              17269
    
     Latency (ms):
              min:                                    0.01
              avg:                                    3.47
              max:                                  373.61
              95th percentile:                        7.84
              sum:                                59957.77
    
     Threads fairness:
         events (avg/stddev):           17269.0000/0.00
         execution time (avg/stddev):   59.9578/0.00

  • 60초동안 랜덤 쓰기 I/O (rndwr)

     $ sysbench --test=fileio --file-test-mode=rndwr --max-time=60 --file-total-size=350G run
     WARNING: the --test option is deprecated. You can pass a script name or path on the command line without any options.
     WARNING: --max-time is deprecated, use --time instead
     sysbench 1.0.17 (using system LuaJIT 2.0.4)
    
     Running the test with following options:
     Number of threads: 1
     Initializing random number generator from current time
    
     Extra file open flags: (none)
     128 files, 2.7344GiB each
     350GiB total file size
     Block size 16KiB
     Number of IO requests: 0
     Read/Write ratio for combined random IO test: 1.50
     Periodic FSYNC enabled, calling fsync() each 100 requests.
     Calling fsync() at the end of test, Enabled.
     Using synchronous I/O mode
     Doing random write test
     Initializing worker threads...
    
     Threads started!
    
     File operations:
         reads/s:                      0.00
         writes/s:                     716.43
         fsyncs/s:                     918.96
    
     Throughput:
         read, MiB/s:                  0.00
         written, MiB/s:               11.19
    
     General statistics:
         total time:                          60.0145s
         total number of events:              98028
    
     Latency (ms):
              min:                                    0.00
              avg:                                    0.61
              max:                                  222.50
              95th percentile:                        4.10
              sum:                                59924.15
    
     Threads fairness:
         events (avg/stddev):           98028.0000/0.00
         execution time (avg/stddev):   59.9242/0.00

  • 60초동안 랜덤 읽기/쓰기 I/O (rndrw) → 테스트용 더미 파일에 문제가 있으면 다시 생성하여 테스트 필요

     $ sysbench --test=fileio --file-test-mode=rndrw --max-time=60 --file-total-size=350G run
     WARNING: the --test option is deprecated. You can pass a script name or path on the command line without any options.
     WARNING: --max-time is deprecated, use --time instead
     sysbench 1.0.17 (using system LuaJIT 2.0.4)
    
     Running the test with following options:
     Number of threads: 1
     Initializing random number generator from current time
    
     Extra file open flags: (none)
     128 files, 2.7344GiB each
     350GiB total file size
     Block size 16KiB
     Number of IO requests: 0
     Read/Write ratio for combined random IO test: 1.50
     Periodic FSYNC enabled, calling fsync() each 100 requests.
     Calling fsync() at the end of test, Enabled.
     Using synchronous I/O mode
     Doing random r/w test
     Initializing worker threads...
    
     Threads started!
    
     File operations:
         reads/s:                      276.83
         writes/s:                     184.55
         fsyncs/s:                     590.81
    
     Throughput:
         read, MiB/s:                  4.33
         written, MiB/s:               2.88
    
     General statistics:
         total time:                          60.0062s
         total number of events:              63016
    
     Latency (ms):
              min:                                    0.00
              avg:                                    0.95
              max:                                  193.77
              95th percentile:                        6.43
              sum:                                59925.04
    
     Threads fairness:
         events (avg/stddev):           63016.0000/0.00
         execution time (avg/stddev):   59.9250/0.00

  • 디스크 속도 벤치마크가 끝나면 cleanup 옵션으로 파일을 삭제해 정리

     $ sysbench --test=fileio cleanup
     WARNING: the --test option is deprecated. You can pass a script name or path on the command line without any options.
     sysbench 1.0.17 (using system LuaJIT 2.0.4)
    
     Removing test files...

  • 리눅스 OS 서버에서 현재 사용 중인 메모리 사용량을 확인하고 캐시 메모리 사용량이 많은 경우 이를 비워서 시스템 효율을 높임
  • /proc/sys/vm/drop을 비움으로써 buff/cache 메모리 항목이 비워지게 됨
  • 캐시는 느린 장치의 데이터를 빠른 장치에 임시 보관해두고 사용함으로써 성능을 높이는 것이 목적 → HIT(적중률)가 낮은 경우엔 캐시를 사용하는 것이 부정적인 영향을 미침
  • 대량의 파일이 관리되는 서버의 파일 cache hit가 낮은데 비해 buffer / cache 메모리 사용량이 높을 경우 해당 cache 기능을 끄거나 주기적으로 비움으로써 성능을 개선 가능
  • 서비스 운영 환경에서는 drop_caches를 하는 것은 위험
  • 기본적으로 memory reclame을 하여 여유 메모리 확보하므로 테스트 등 특별한 경우에만 사용하면됨


/proc/sys/vm/drop_caches에 숫자를 추가하여 리눅스 캐시 메모리 관리

1. pagecache 해제 명령어 (echo 1 > /proc/sys/vm/drop_caches)

$ free -m
              total       used       free     shared    buffers     cached
 Mem:          1999       1983         15        392         90       1490
 -/+ buffers/cache:        402       1596
 Swap:         2047          5       2042

 $ echo 1 > /proc/sys/vm/drop_caches

 $ free -m
             total       used       free     shared    buffers     cached
 Mem:          1999        956       1042        392          8        539
 -/+ buffers/cache:        408       1590
 Swap:         2047          5       2042

2. dentry 및 inode 캐시메모리 해제 명령어 (echo 2 > /proc/sys/vm/drop_caches)

$ echo 2 > /proc/sys/vm/drop_caches

3. pagecache, dentry, inode 캐시메모리 모두 해제 명령어 (echo 3 > /proc/sys/vm/drop_caches)

$ free -m
             total       used       free     shared    buffers     cached
 Mem:          1999       1011        987        392         36        609
 -/+ buffers/cache:        365       1633
 Swap:         2047          5       2042

 $ echo 3 > /proc/sys/vm/drop_caches

 $ free -m
             total       used       free     shared    buffers     cached
 Mem:          1999        875       1123        392         11        511
 -/+ buffers/cache:        352       1646
 Swap:         2047          5       2042



크론탭(crontab)을 사용하여 시스템이 주기적으로 메모리 관리

$ crontab -e 
 # 크론탭 편집 모드에서 아래와 같이 입력
 # 매일 새벽 3시에 시스템이 자동으로 전체 캐시 메모리를 비우는 명령
0 3 * * * sync && echo 3 > /proc/sys/vm/drop_caches



리눅스 캐시 메모리와 연결돤 용어 정리

1. pagecache

  • 리눅스 파일 I/O의 성능 향상을 위해 페이지 캐시라는 메모리 영역을 만들어 사용
  • 상대적으로 느린 디스크로의 접근을 최대한 피하기 위해서 사용하는 영역
  • 파일의 내용을 페이지 캐시 영역에 저장시켰다가 다시 한번 동일한 파일 접근이 일어나면 디스크에서 읽지 않고 페이지 캐시에서 읽어서 제공해 주는 방식
  • pachecache 확인 테스트

    1. 파일을 읽기 전의 메모리 양을 free로 확인 → cached 영역이 78516 KB 확인

    2. 24 KB 정도 되는 파일을 cat 명령어로 읽은 후 메모리 양을 확인 → 24KB 만큼 cached 영역이 늘어남을 확인 가능


2. dentry

  • directory entry의 줄임말로 /usr/share 같은 경로에서 usr과 share를 지칭.
  • Dentry는 해당 디렉토리가 포함하고 있는 디렉토리와 파일정보를 보유하고 있음
  • dentry는 경로명 탐색을 위한 캐시 역할도 수행한다고 알려져 있음
  • 빠른 데이터 접근을 위해 Slab의 자료구조에 추가되어 사용

3. inode

  • 모든 파일이나 디렉토리에는 1개의 inode를 가지고있음(1개의 inode는 64byte로 이루어짐)
  • 각 inode에는 파일의 소유권, 허가권, 파일 종류 등의 정보, 파일의 실제 데이터가 어디에 있는지 위치(=주소) 보유
  • inode가 모여있는 공간이 inode 블록 → (전체 디스크의 1%정도를 차지)
  • 빠른 데이터 접근을 위해 Slab의 자료구조에 추가되어 사용
  • inode 확인 명령어 ( ls- il )

Timeout이란

  • 프로그램이 특정한 시간 내에 성공적으로 수행되지 않아서 진행이 자동적으로 중단되는 현상
  • 응답을 무한정 기다릴 수 없기 때문에 기다릴 시간을 정해야 함


1. Connection Timeout

  • 클라이언트가 서버와 연결을 맺지 못하는 경우 발생하는 Timeout을 Connection Timeout이라고 함

  • 3-Way Handshake을 정상적으로 수행해야지 클라이언트와 서버가 정상적으로 연결을 맺었다고 말할 수 있음

  • 3-Way Handshake 연결(Connection)에 소요된 시간 → Connection Timeout은 연결을 하는데 소요되는 시간의 임계치

  • Connection time을 무한으로 설정할 수는 없으니까 일정 시간을 지정하여 무한정 연결을 제한


  • Connection Timeout 사례 예시

    • 히포가 유명맛집을 인터넷에서 검색하고 맛집에 찾아갑니다.
    • 맛집에는 이미 많은 사람들이 찾아와 북적이고 대기열도 한가득 있었습니다.
    • 성질급한 히포는 “이거하나 먹으려고 이리 오래 기다려야되나?" 라고 생각하고 “10분만 기다려보고 안되면 다른데 가야겠다”라고 결정을 내렸습니다.
    • 10분을 기다렸지만 대기열은 줄어들지 않아 히포는 맛집은 들어가보지도 못한채 다음에 와봐야겠다 생각하고 집으로 돌아갔습니다.
    • 서버(맛집)자체에 클라이언트(히포)가 어떤 사유로 접근을 실패했을시 적용되는것이 Connection timeout입니다.
    • 접근을 시도하는 시간제한이 Connection Timeout이 되는 것입니다.


2. Socket Timeout

  • 클라이언트와 서버가 정상적으로 연결된 이후에 발생
  • 서버는 클라이언트에게 응답 메세지를 전달할 때, 하나의 메세지를 여러 개의 패킷(packet)으로 나누어 전달
  • 각 패킷이 전송될 때 시간 갭이 발생할 수 있는데 시간이 초과된 것 → 서버에서 클라이언트 전달할 때 시간 간격인 Socket Timeout 발생
  • 클라이언트가 응답에 대한 패킷을 전달받을 때 시간 차이가 발생 → 발생하는 시간 차이의 임계치가 Socket Timeout
  • 전체 연결이 타임아웃이 발생한 것이 아니고 개별 패킷이 타임아웃이 발생



3. ConnectionTimeout과 SocketTimeout의 차이 (웹 브라우저에서 네이버에 접속)

  • URL을 호출할 때에는 ConnectionTimeout과 SocketTimeout 설정이 모두 필요
  • 두 가지 Timeout을 설정하지 않으면 URL 접속시 무한 대기 가능
  • OS 레벨에서 Timeout이 설정되어 있는 경우 그 설정값이 적용됨


3.1. 웹 브라우저가 네이버 서버에 접속하기 위해 서버와 연결

  • 연결을 구성하기 위해서 보통 TCP Connection과 동일하게 3-way Handshake 방식으로 수행
  • 3-way Handshake를 정상적으로 수행하게 되면 웹 브라우저와 네이버 서버는 연결된 상태가 됨
  • 3-way Handshake에 소요된 시간을 Connection에 소요된 시간이라고 함
  • ConnectionTimeout은 Connection을 구성하는데 소요되는 시간의 임계치를 의미


3.2. 클라이언트와 서버가 연결된 상태에서 서버는 데이터를 클라이언트로 전송

  • 하나의 패킷이 아니라 여러 개의 패킷으로 나눠서 전송
  • 여러 패킷을 전솔할 때, 각 패킷이 전송될 때 시간 Gap이 발생 가능
  • 패킷이 전송하는 시간의 임계치를 SocketTimeout


3.3. ConnectionTimeout과 SocketTimeout 비교




4. Read Timeout

  • Read Timeout도 Socket Timeout과 마찬가지로 서버와 정상적인 연결은 된 이후에 발생
  • 서버가 클라이언트의 요청을 받아 처리하는 시간이 길어지게 되는 경우 Read Timeout이 발생 → 요청에 대한 응답이 없어서 발생
  • 클라이언트가 특정 시간동안 서버로부터 요청에 대한 응답을 받지 못함
  • 주고 받는 데이터의 양이나 네트워크 속도에 따라서 대응을 다름
  • 데이터의 양이 크다면 이를 분할해서 받을 수 있도록 API 자체 Spec을 변경하거나 Retry 전략을 사용
  • 속도가 느려서 발생하는 상황이라면 전반적으로 네트워크 대역폭 증가를 위한 인프라 작업을 필요
  • Read Timeout 사례 예시
    • 히포가 대기열을 뚫고 맛집안까지 들어가서 메뉴를 주문하는데까진 성공을 했습니다.
    • 근데 워낙에 사람이 많다보니 이번엔 주문한 메뉴가 나오는데 많은 시간이 필요했습니다.
    • 주방에서 뭔짓을 하는지 아무리 기다려도 주문한 음식은 나오지가 않습니다.
    • 성질급한 히포는 “아오! 그냥 이시간에 딴걸할걸 바빠 죽겠는데” 하고 그냥 가게를 나와버립니다.
    • 나중에 히포이가 주문한 음식은 나왔지만 이미 음식을 먹을 사람은 사라지고 없어져, 결국 요리는 버려지게 됩니다.
    • client가 server에 접속을 성공 했으나 서버가 로직을 수행하는 시간이 너무 길어 제대로 응답을 못 준상태에서 client가 연결을 해제하는것이 Read timeout입니다.
    • client는 해당상황을 오류로 인지(요리가 안나옴)하고 server는 계속 로직(주문된 요리)을 수행하고 있어 성공으로 인지해 양사이드간에 싱크가 맞지 않아 문제가 발생할 확률이 높습니다.


  • 페이로드(payload)는 전송되는 데이터를 의미
  • 데이터를 전송할 때, 헤더와 메타데이터, 에러 체크 비트 등과 같은 다양한 요소들을 함께 보내어, 데이터 전송의 효율과 안정성을 높히게 됨
  • 보내고자 하는 데이터 자체를 의미하는 것을 페이로드라고 함


실생활 예시

  • 우리가 택배 배송을 보내고 받을 때, 택배 물건이 페이로드
  • 송장이나 박스, 뾱뾱이와 같은 완충재 등등은 부가적인 것으로 페이로드가 아님


위키피디아에 이해하기 좋은 예시

  • json으로 보는 실제 데이터에서의 payload는 아래의 json에서 “data” 부분만 해당
  • 그 이외의 데이터들은 전부 통신을 하는데 있어 용이하게 해주는 부차적인 정보들
    {
      "status" :
      "from": "localhost",
      "to": "http://melonicedlatte.com/chatroom/1",
      "method": "GET",
      "data":{ "message" : "There is a cutty dog!" }
    }


Payload 참고 그림



※ 참고) 페이로드(payload)의 유래

  • 운송업에서 비롯된 것으로 지급(pay)해야 하는 적화물(load)을 의미
  • 예를 들어, 유조선 트럭이 20톤의 기름을 운반한다면 트럭의 총 무게는 차체, 운전자 등의 무게 때문에 기름의 무게보다 더 무겁게 된다.
  • 모든 무게를 운송하는데 비용이 발생하지만, 고객은 오로지 기름의 무게에만 비용을 지급
    ‘pay-load’란 말이 나온 것

'IT 학습 용어' 카테고리의 다른 글

CI/CD 설명  (0) 2022.07.07
file storage, block storage, object storage이란  (0) 2022.07.03
M3U8 파일  (0) 2022.06.27
LRU (Least Recently Used)  (0) 2022.06.27
Consistent Hashing 정리  (0) 2022.06.24

+ Recent posts