Android 고성능 로그 기록 프로젝트 의 실현

머리말
회 사 는 현재 기업 급 스마트 고객 지원 시스템 을 만 들 고 있 으 며 시스템 안정성 에 대한 요구 가 높 지만 사용자 가 사용 하 는 데 문제 가 없 을 것 이 라 고 보장 하기 어렵 고,안 드 로 이 드 SDK 는 고객 의 앱 에 통합 되 어 있 으 며,안 드 로 이 드 파편 화 문제 로 SDK 에 대한 조사 가 특히 어려워 사용자 의 조작 로 그 를 기록 하 는 것 이 중요 하 다.
초기 계획
처음에는 SDK 가 로 그 를 기록 하 는 방식 은 파일 을 직접 작성 하 는 것 이 었 습 니 다.로 그 를 기록 할 때 먼저 파일 을 열 고 로 그 를 기록 한 다음 파일 을 닫 습 니 다.이렇게 하 는 문 제 는 잦 은 IO 작업 으로 프로그램의 성능 에 영향 을 주 고 SDK 는 메시지 의 신속 성 을 확보 하기 위해 백 엔 드 프로 세 스 를 유지 하고 있 으 며,그 중 하 나 는 로 그 를 기록 할 때 다른 하 나 는 문 밖 에 잠 겨 기다 리 고 있어 문제 가 더욱 심각 해 집 니 다.이 방안 을 사용 하 는 것 은 현재 프로그램 에 미 치 는 영향 이 크 지 않 지만 로그 의 양 이 증가 함 에 따라 더 많은 IO 작업 은 반드시 성능 병목 을 초래 할 것 이다.
파일 을 직접 쓰 는 절 차 를 분석 해 보 겠 습 니 다.
  • 사용자 가 write 작업 을 시작 합 니 다
  • 운영 체제 검색 페이지 캐 시
    a.명중 하지 않 으 면 페이지 이상 이 발생 한 다음 에 페이지 캐 시 를 만 들 고 사용자 가 들 어 온 내용 을 페이지 캐 시 에 기록 합 니 다.
    b.명중 하면 사용자 가 들 어 온 내용 을 페이지 캐 시 에 직접 기록 합 니 다
  • 사용자 write 호출 완료
  • 페이지 가 수정 되면 더러 운 페이지 가 되 고 운영 체제 에는 두 가지 메커니즘 이 있어 더러 운 페이지 를 디스크 에 다시 쓴다.
    a.사용자 가 fsync()를 수 동 으로 호출 합 니 다.
    b.pdflush 프로 세 스 가 정시 에 더러 운 페이지 를 디스크 에 다시 쓰기
  • 이 를 통 해 알 수 있 듯 이 데 이 터 는 프로그램 에서 디스크 에 기록 하 는 과정 에서 두 번 의 데이터 복사 와 관련된다.하 나 는 사용자 공간 메모리 에서 커 널 공간 으로 복사 하 는 캐 시 이 고 하 나 는 다시 쓸 때 커 널 공간의 캐 시 에서 하 드 디스크 로 복사 하 는 것 이다.리 턴 이 발생 했 을 때 커 널 공간 과 사용자 공간 이 빈번하게 전환 되 는 것 도 관련 되 었 다.
    그리고 기계 하 드 디스크 에 비해 SSD 저장 소 는'기록 확대'문제 가 하나 더 있다.이 문 제 는 주로 SSD 에 저 장 된 물리 적 구조 와 관련 이 있다.SSD 가 모두 한 번 쓰 인 후에 기 록 된 데 이 터 는 직접 업데이트 할 수 없고 덮어 쓰기 로 만 다시 쓸 수 있 으 며 덮어 쓰기 전에 데 이 터 를 지 워 야 합 니 다.그러나 가장 작은 단 위 는 Page 입 니 다.지 울 가장 작은 단 위 는 Block 입 니 다.Block 은 Page 보다 훨씬 크기 때문에 새로운 데 이 터 를 쓸 때 먼저 Block 의 데 이 터 를 읽 고 쓸 데이터 와 합 친 다음 에 Block 을 지우 고 마지막 으로 읽 은 데 이 터 를 저장 소 에 다시 써 야 합 니 다.이렇게 하면 실제 기록 한 데 이 터 는 처음에 기록 해 야 할 데이터 보다 훨씬 클 수 있 습 니 다.
    간단 한 파일 쓰기 가 이렇게 많은 조작 과 관련 될 줄 은 몰 랐 다.단지 응용 층 에 대한 투명 일 뿐이다.
    파일 을 쓸 때마다 이렇게 많은 작업 을 수행 하 는 이상 로 그 를 캐 시 할 수 있 습 니 다.일정한 수량 에 이 르 렀 을 때 디스크 에 한꺼번에 기록 할 수 있 습 니까?
    이렇게 하면 확실히 IO 횟수 를 대량으로 줄 일 수 있 지만,또 다른 심각 한 문 제 를 일 으 킬 수 있다.
    메모리 에 로그 캐 시 를 저장 합 니 다.프로그램 이 Crash 나 프로 세 스 가 죽 으 면 로그 의 완전 성 을 보장 할 수 없습니다.또한 SDK 에 여러 프로 세 스 가 존재 하기 때문에 여러 프로 세 스 가 로그 의 순 서 를 보장 할 수 없습니다.
    완벽 한 로그 방안,만족 이 필요 합 니 다.
  • 효율 적 이 고 시스템 성능 에 영향 을 주지 않 으 며 로그 모듈 을 도입 했다 고 해서 응용 이 중단 되 어 서 는 안 된다
  • 로그 의 완전 성 을 보장 합 니 다.로그 의 완전 성 을 보장 하지 못 하면 로그 수집 은 의미 가 없습니다
  • 다 중 프로 세 스 응용 에 대해 최종 적 으로 보 이 는 로그 순서 의 정확성 을 확보 해 야 합 니 다
  • 고성능 프로젝트
    기록 횟수 를 줄 일 수 없 으 니 파일 을 쓰 는 과정 에서 최적화 할 수 있 을까요?
    정 답 은 가능 합 니 다.mmap 를 사용 하 세 요.
    mmap 는 메모리 매 핑 파일 의 방법 입 니 다.파일 이나 다른 대상 을 프로 세 스 의 주소 공간 에 매 핑 하여 파일 디스크 주소 와 프로 세 스 가상 주소 공간 에서 가상 주소 의 일대일 대 영 관 계 를 실현 합 니 다.함수 원형 은 다음 과 같 습 니 다.
    
    void *mmap(void *addr, size_t length, int prot, int flags, int fd, off_t offset);
     
    mmap 작업 은 사용자 프로그램 이 장치 메모리 에 직접 접근 하도록 하 는 체 제 를 제공 합 니 다.이런 체 제 는 사용자 공간 과 커 널 공간 에서 서로 데 이 터 를 복사 하 는 것 에 비해 효율 이 높 습 니 다.고성능 을 요구 하 는 응용 에서 비교적 자주 사용 된다.
    시간 mmap 는 로그 의 완전 성 을 확보 할 수 있 습 니 다.mmap 의 재 작성 시기:
  • 메모리 부족
  • 프로 세 스 종료
  • msync 또는 munmap
  • 호출
  • MAP 설정 하지 않 음NOSYNC 의 경우 30s-60s(FreeBSD 만 가능)
  • 파일 을 매 핑 하면 프로그램 은 native 메모리 에 같은 크기 의 공간 을 신청 합 니 다.따라서 64k 와 같은 작은 내용 을 매 핑 할 때마다 가득 쓴 후에 파일 뒤의 내용 을 다시 매 핑 하 는 것 을 권장 합 니 다.
    로그 기록 성능 과 완전 성 문제 가 해결 되 었 습 니 다.다 중 프로 세 스 에서 로그 의 순 서 를 어떻게 보장 합 니까?
    mmap 는 공유 메모리 방식 으로 데 이 터 를 기록 하기 때문에 두 프로 세 스 가 파일 을 동시에 비 추 면 로그 덮어 쓰기 문제 가 발생 할 수 있 습 니 다.
    순 서 를 직접 보장 할 수 없 는 이상,두 프로 세 스 는 각각 다른 파일 을 매 핑 하고,매일 한 번 씩 합 쳐 서 로 그 를 정렬 할 수 밖 에 없습니다.
    계속 최적화
    상기 방안 에 따 르 면 jni 인 터 페 이 스 를 설계 하고 so 를 포장 하여 SDK 를 도입 하 는 것 은 문제 가 없 을 것 같 지만 SDK 로 서 so 를 포함 하 는 것 이 우호 적 이지 않 고 어느 정도 접속 의 어려움 을 증가 시 킬 것 이 라 고 생각 합 니 다.
    그럼 so 를 안 써 도 될까요?
    사실 자바 에 서 는 메모리 맵 의 실현―MappedByteBuffer 를 제공 했다.
    MappedByteBuffer 는 자바 NIO 패키지 에 위치 하여 파일 내용 을 버퍼 에 비 추 는 데 사용 되 며,mmap 기술 을 사용 합 니 다.FileChannel 의 map 방법 을 통 해 버퍼 를 만 들 수 있 습 니 다.
    
    RandomAccessFileraf = new RandomAccessFile(file, "rw");
    MappedByteBuffer buffer = raf.getChannel().map(FileChannel.MapMode.READ_WRITE, position, size);
    MappedByteBuffer 의 효율 을 테스트 하기 위해 서,우 리 는 64byte 의 데 이 터 를 각각 메모리,MappedByteBuffer 와 디스크 파일 50 만 번 을 기록 하고,시간 을 통계 합 니 다.
    방법.
    시간 을 소모 하 다
    메모리
    384ms
    MappedByteBuffer
    700ms
    디스크 파일
    16805ms
    이 를 통 해 알 수 있 듯 이 MappedByteBuffer 는 메모리 에 쓰 는 성능 에 미 치지 못 하지만 디스크 파일 에 쓰 는 것 과 비교 하면 질 적 으로 향상 되 었 다.
    총결산
    본 고 는 파일 기록 로 그 를 직접 작성 하 는 방식 에 존재 하 는 문제점 을 분석 하고 고성능 파일 기록 방안 인 mmap 를 도입 하여 기록 성능 과 완전 성 을 고려 하 였 으 며 보상 방안 을 통 해 다 중 프로 세 스 로그 의 순 서 를 확보 하 였 다.마지막 으로 메모리 가 자바 층 에 비 치 는 실현 을 발견 하여 so 도입 을 피 했다.
    자,이상 이 이 글 의 전체 내용 입 니 다.본 논문 의 내용 이 여러분 의 학습 이나 업무 에 어느 정도 참고 학습 가치 가 있 기 를 바 랍 니 다.궁금 한 점 이 있 으 시 면 댓 글 을 남 겨 주 셔 서 저희 에 대한 지지 에 감 사 드 립 니 다.

    좋은 웹페이지 즐겨찾기