2016년 9월 23일 금요일

Mongodb (시스템 Openfile limit 제한으로 인한 비정상종료 분석)

  1. 현상 
    1. Mongodb 가 Open file Limit 제한값을 넘어 비정상 종료하는 Case 가 발생함. (리눅스 파일 Open 제한값을 넘어 논리 리소스 한계치에 도달하여 비정상 종료 발생 ) 
      [  로그 내용 ]
      2016-08-29T17:10:37.815+0900 I NETWORK  [thread1] connection accepted from X.X.X.X :50297 #61339 (788 connections now open)
      2016-08-29T17:10:37.905+0900 I NETWORK  [thread1] Listener: accept() returns -1 Too many open files
      2016-08-29T17:10:37.905+0900 E NETWORK  [thread1] Out of file descriptors. Waiting one second before trying to accept more connections.
      2016-08-29T17:10:37.921+0900 E -        [conn61339] cannot open /dev/urandom Too many open files
      2016-08-29T17:10:38.007+0900 I -        [ftdc] Assertion: 13538:couldn't open [/proc/30427/stat] Too many open files src/mongo/util/processinfo_linux.cpp 74
      #2016-08-29T17:10:38.019+0900 I -        [conn61339] Fatal Assertion 28839 at src/mongo/platform/random.cpp 158
  2. 이유  
    1. 기존  리눅스가 세팅될 때 기본적으로 Ulimit -n 값 ( Open files limit) 제한 값을 65000 으로 세팅하고 있으며, 기존 부터 계속 확인하던 값이 였음. (Centos 6.* )
      1. 해당 제한값을 세팅한 유저에서 프로세스를 기동하게 되면 , 프로세스 기동시 해당 제한값을 참조하며 구동되게 됨. (원래는 ................)
    2. 해당 값의 의미는 해당 유저에서 동작하는 프로세스가 최대로 열수 있는 파일 및 소켓의 갯수 제한이며, 해당 제한 값을 두는 이유는 보안 공격등을 받을 때 무한정 파일이 늘어 나게 되면
      시스템 리소스를 모두 점유하게되어, 시스템 Hang 이 발생할 수 있고,  다른 유저가 사용하는 리소스를 다 점유해버릴 수 있기 때문임.
    3. 보통 Mysql 및 타 DBMS 도 해당 제한값을 참조하며, 해당 제한값을 넘을 경우 프로세스를 비정상 종료 시킴 ( FATAL )

       
  3. 원인 
    1. Centos 7 이상에서 Systemd 라는 데몬으로 Service 를 관리 하게 되는데, 이때 Systemd 로 프로세스를 기동하면 특정 유저의 Open files limit 제한값을 읽지 않고  Default 값인 1024 를 읽고 올라가는 것을 확인함.   
    2. 따라서 로그상에서 788 Connection(소켓) + Mongodb 가 현재 열고 있는 파일 약 200 + Dynamic Library (100)  개 정도를 합쳐 1024 개를 넘어 비정상 종료 발생 . 
    3. 즉 Mongodb 가 연결소켓 및 data 파일,log 파일등을 1024개 까지 밖에 열수 없음.

  4. 해결방안 
    1. Centos 7 버전대 이상에서 Systemd (기존 Centos 6에서는 service mongodb start 등을 사용함) 를 사용하여, 프로세스를 기동하여 사용할 경우 Systemd 의 Conf 파일에 해당 프로세스의  ulimit 값을 명시 해야함.
    2. 기존 service 도 사용가능하나 , 버전이 Up 될수록 차츰 없어질 수 있으며,  service 를 사용하는 것은 해당 내용관계없음
    3. Systemd 수정 내용 
      [ systemd 의  mongodb.service 변경 값 ]
       
      [Unit]
      Description=An object/document-oriented database
      Documentation=man:mongod(1)
      After=network.target
      [Service]
      User=mongodb
      Group=mongodb
      ExecStart=/usr/bin/mongod --storageEngine=rocksdb -f /etc/mongod.conf --rest
       
      #### 아래 내용을 추가 해야 함. #####
      # (file size)
      LimitFSIZE=infinity
      # (cpu time)
      LimitCPU=infinity
      # (virtual memory size)
      LimitAS=infinity
      # (open files)
      LimitNOFILE=64000
      # (processes/threads)
      LimitNPROC=64000
       
       
      [Install]
      WantedBy=multi-user.target
       
  5. Comment 
    1. 앞으로 Centos 7점대 버전들을 계소 사용하게 될것이고,  모든 소켓 및 파일을 여는 DB 및 Nosql 들을 Systemd 로 등록하여 사용할 때 , 위 제한 값을 세팅하지 않아 비정상 종료할 수 도 있으니, 꼭 확인해야함


댓글 없음:

댓글 쓰기