주의 사항 : 아래에 부정확 한 내용이있을 수 있습니다. 나는 내가 따라갈 때이 물건에 대해 많이 배웠으므로 소금 한 덩어리로 가져갑니다. 이것은 꽤 길지만, 우리가 가지고 있던 매개 변수를 읽은 다음 끝에 결론으로 건너 뛸 수 있습니다.
SQLite 쓰기 성능에 대해 걱정할 수있는 여러 계층이 있습니다.
우리는 굵은 글씨로 강조된 것을 보았습니다. 특정 매개 변수는
- 디스크 쓰기 캐시 최신 디스크에는 회전 디스크에 대한 디스크 쓰기를 최적화하는 데 사용되는 RAM 캐시가 있습니다. 이 기능을 사용하면 데이터를 비 순차적 블록으로 쓸 수 있으므로 충돌이 발생하면 부분적으로 작성된 파일로 끝날 수 있습니다. hdparm -W / dev / ...로 설정을 확인하고 hdparm -W1 / dev / ...로 설정하십시오 (설정하려면 -W0, 끄려면 -W0).
- 장벽 = (0 | 1). "barrier = 0으로 실행하면 디스크 쓰기 캐싱이 활성화되어 있지 않습니다"라는 온라인 댓글이 많이 있습니다. 장벽에 대한 토론은 http://lwn.net/Articles/283161/ 에서 찾을 수 있습니다.
- data = (저널 | 주문 | 쓰기 저장). 봐 http://www.linuxtopia.org/HowToGuides/ext3JournalingFilesystem.html 이러한 옵션에 대한 설명.
- commit = N. ext3에게 N 초마다 모든 데이터와 메타 데이터를 동기화하도록 지시합니다 (기본값 5).
- SQLite pragma 동기식 = ON | 떨어져서. ON으로 설정하면 SQLite는 계속하기 전에 트랜잭션이 "디스크에 기록"되도록합니다. 이 기능을 끄면 다른 설정은 크게 관련이 없습니다.
- SQLite pragma cache_size. SQLite가 메모리 내 캐시에 사용할 메모리 양을 제어합니다. 전체 DB가 캐시에 적합한 크기와 캐시가 최대 DB 크기의 절반 인 두 가지 크기를 시도했습니다.
ext3 문서 에서 ext3 옵션에 대한 자세한 내용을 읽으십시오 .
이러한 매개 변수의 여러 조합에 대해 성능 테스트를 실행했습니다. ID는 아래에 언급 된 시나리오 번호입니다.
시나리오 1과 같이 컴퓨터에서 기본 구성으로 실행하여 시작했습니다. 시나리오 2는 "가장 안전한"것으로 가정 한 다음 적절한 / 프롬프트 된 다양한 조합을 시도했습니다. 이것은 내가 사용한지도를 이해하는 것이 가장 쉬운 방법입니다.
INTEGER 전용, TEXT 전용 (ID 열 포함) 또는 혼합 테이블에서 모두 삽입, 업데이트 및 삭제와 함께 많은 트랜잭션을 실행하는 테스트 스크립트를 작성했습니다. 위의 각 구성에서 여러 번 실행했습니다.
맨 아래 두 시나리오는 # 6 및 # 17이며 "pragma synchronous = off"가 있으므로 가장 빠르지 않습니다. 다음 세 군집은 # 7, # 11 및 # 19입니다. 이 3 개는 위의 "구성 맵"에서 파란색으로 강조 표시되어 있습니다. 기본적으로 구성은 디스크 쓰기 캐시 켜기, barrier = 0 및 데이터가 'journal'이외의 것으로 설정됩니다. 5 초 (# 7)와 60 초 (# 11) 사이에서 커밋을 변경하면 별 차이가 없습니다. 이 테스트에서 data = ordered와 data = writeback의 차이점이별로 놀랍지 않은 것처럼 보였습니다.
혼합 갱신 시험은 중간 피크입니다. 이 테스트에서 더 느리게 진행되는 시나리오 클러스터가 있습니다. 이들은 모두 data = journal 인 것들 입니다 . 그렇지 않으면 다른 시나리오 사이에는 그리 많지 않습니다.
다른 유형 조합에서 삽입, 업데이트 및 삭제의 이종 혼합을 수행하는 다른 타이밍 테스트가있었습니다. 이것들은 훨씬 오래 걸렸으므로 위의 플롯에 포함시키지 않았습니다.
여기에서 쓰기 저장 구성 (# 19)이 주문 된 구성 (# 7 및 # 11)보다 약간 느리다는 것을 알 수 있습니다. 쓰기 속도가 약간 빠를 것으로 예상했지만 쓰기 패턴에 따라 다르거 나 ext3에서 아직 충분히 읽지 못했을 수도 있습니다 :-)
다양한 시나리오는 애플리케이션에서 수행 한 작업을 다소 나타 냈습니다. 짧은 시나리오 목록을 선택한 후 자동화 된 테스트 스위트를 사용하여 타이밍 테스트를 실행했습니다. 그들은 위의 결과와 일치했습니다.
결론
- 커밋 우리가 5 초에 있음을 떠난다 있도록 매개 변수는 약간의 차이를 보였다.
- 디스크 쓰기 캐시를 켜고 barrier = 0 및 data = ordered로 진행 합니다. 온라인에서 이것이 잘못된 설정이라고 생각한 것들과 많은 상황에서 이것이 기본값이어야한다고 생각한 것들을 읽었습니다. 가장 중요한 것은 당신이 어떤 절충을하고 있는지를 알고 현명한 결정을 내리는 것입니다.
- 우리는 SQLite에서 동기식 pragma를 사용하지 않을 것입니다.
- SQLite cache_size pragma를 설정하여 예상대로 DB가 일부 작업의 메모리 향상 성능에 맞도록합니다.
- 위의 구성은 약간 더 위험을 감수한다는 의미입니다. 우리는 사용하고있을 것입니다 SQLite는 백업 API를 스냅 샷마다 N 분을 복용하고, 주위의 마지막 M을 유지 : 부분 쓰기에 디스크 실패의 위험을 최소화 할 수 있습니다. 성능 테스트를 실행하는 동안이 API를 테스트했으며이 방법으로 갈 수 있다는 확신을 얻었습니다.
- 여전히 더 많은 것을 원한다면 커널을 살펴볼 수는 있지만 거기에 가지 않고도 충분히 개선 할 수있었습니다.
다양한 팁과 포인터를 제공하는 @Huygens에게 감사드립니다.