2016-07-10 2 views
2

나는 ~ 500 실시간 방문자, ~ 5 만 매일 방문자~ 1,3million 총 사용자을 가진 웹 사이트를 실행합니다. AWS에 내 서버를 호스팅합니다. 여기에서는 다른 종류의 인스턴스를 여러 개 사용합니다. 웹 사이트를 시작했을 때 다른 인스턴스 비용은 거의 같지 않았습니다. 웹 사이트가 RDS 인스턴스 (MySQL DB) CPU를 지속적으로 사용하여 사용자를 확보하기 시작했을 때 여러 번 업그레이드해야했지만 이제는 성능 및 월간 비용의 주요 부분을 차지하기 시작했습니다 (약 95 %). (2,8k $/월)). 현재 16vCPU 및 64GiB RAM의 데이터베이스 서버를 사용하고 있으며 다중 AZ 배포를 사용하여 오류를 방지합니다. 데이터베이스가 비싸거나 정상적으로 작동하는지 궁금한 점이 있습니까? 순간 MySQL 서버 매우 높은 부하

enter image description here

데이터베이스 정보

Current settings 내 데이터베이스는 일부 ~ 2millions이 1 30 개 수백만 달러를 가지고, 100,000 행이 그 중 가장 40 개 테이블이있다. 나는 더 이상 필요하지 않은 21 일이 지난 보관소 시스템을 보관하고 있습니다.

웹 사이트 정보

웹 사이트는 주로 PHP를 사용하지만 일부 NodeJS와 파이썬.

는 웹 사이트의 대부분의 기능은 다음과 같이 작동합니다

  1. 마지막 ID를 삽입하기
  2. 시작 트랜잭션
  3. 행 삽입 (lastrowid)
  4. 가 삽입 된 업데이트 된 몇 가지 계산을 수행 행
  5. 사용자 업데이트
  6. 커밋 트란 보장

또한 10-30 초 간격으로 데이터베이스에서 폴링하는 약 100bots를 실행하며 데이터베이스를 때때로 삽입/업데이트합니다.

나는 데이터베이스의 부하를 낮추기 위해 시도하는 몇 가지 일을 한

추가. 데이터베이스 캐시를 활성화하고, 일부 쿼리에 redis 캐시를 사용하고, 매우 느린 쿼리를 제거하려고 시도하여 스토리지 유형을 "프로비저닝 된 IOPS SSD"로 업그레이드하려고했습니다. 그러나 아무것도 도움이되는 것 같지 않습니다.

내가 설정 paramters에 수행 한 변경입니다 :

enter image description here

, 나는 여러 개의 작은 인스턴스의 MySQL의 클러스터를 만드는 방법에 대한 생각,하지만이 도움이 될 경우 나도 몰라 및 나는 또한 이것이 거래와 잘 작동하는지 모른다.

자세한 내용이 필요하면이 문제에 대한 도움을 받으십시오.

+0

프로비저닝 된 IOPS로 업그레이드하려고했지만 이미 사용할 수있는 IOPS를 초과 했습니까? 여전히 사용 가능한 IOPS를 극대화하고 있습니까? "초당 읽기 작업"및 "초당 쓰기 작업"을보고 사용 가능한 IOPS에 의해 제한되는지 확인해야합니다. –

+0

또한 오로라가 더 나은 성능을 발휘하는지 테스트 해 볼 것을 제안합니다. –

답변

5

제 경험상, "성능을 어떻게 확장 할 수 있습니까?"라는 질문을하는 즉시 당신은 당신이 RDS (편집 : 나는이 의견으로 나를 인도하는 나의 경험을 인정할 수있다 구식일지도 모른다)를 능가했다는 것을 알고있다.

쿼리로드가 꽤 쓰기가 심한 것처럼 들립니다. 많은 삽입 및 업데이트. 자신의 RDS 버전에서 innodb_log_file_size를 늘려야합니다. 그렇지 않으면 RDS를 포기하고 MySQL을 더 쉽게 조정할 수있는 EC2 인스턴스로 이동해야 할 수 있습니다.

나는 또한 MySQL 쿼리 캐시를 비활성화합니다. 매 삽입/갱신시, MySQL은 질의 캐시를 스캔하여 제거되어야하는 결과가 캐시되어 있는지 확인해야한다. 쓰기 작업량이 많은 경우 시간 낭비입니다. 쿼리 캐시를 2.56GB로 늘리면 성능이 더욱 악화됩니다! 캐시 크기를 0으로 설정하고 캐시 유형을 0으로 설정하십시오.

어떤 쿼리를 실행했는지, 또는 얼마나 잘 최적화했는지는 알지 못합니다. MySQL의 옵티 마이저는 제한적이므로 SQL 쿼리를 재 설계함으로써 많은 이점을 얻을 수 있습니다. 즉, 쿼리 구문을 변경하고 올바른 인덱스를 추가하는 것입니다.

쿼리 감사를 수행하여 부하가 많은 쿼리를 찾아야합니다. 이를 수행 할 수있는 무료 도구는 느린 쿼리 로그를 기반으로 보고서를 제공 할 수있는 https://www.percona.com/doc/percona-toolkit/2.2/pt-query-digest.html입니다. http://docs.aws.amazon.com/cli/latest/reference/rds/download-db-log-file-portion.html CLI 명령을 사용하여 RDS 저속 쿼리 로그를 다운로드하십시오.

long_query_time = 0으로 설정하고 잠시 동안 정보를 수집 한 다음 long_query_time을 평소 사용하는 값으로 변경하십시오. 이 로그에서 모든 쿼리를 수집하는 것이 중요합니다.로드의 75 %는 2 초 미만의 쿼리에서 발생하지만 너무 자주 실행되기 때문에 서버에 부담이됩니다. 응용 프로그램에서

  • 더 많은 캐시를
  • 스케일 아웃

    • 쿼리 최적화 또는 재 설계 :

      당신은 쿼리 부하를 차지되는 알고 후, 당신은이를 해결하는 방법에 대한 몇 가지 정보 전략을 만들 수 있습니다 더 많은 경우

  • +0

    나는 왜 그들이 "자란 RDS"를 가지고 있다고 생각하는지 궁금합니다. RDS를 사용하면서 제안 할 수있는 모든 조정 작업을 수행 할 수있는 것처럼 보입니다. –

    +0

    내 의견이 오래된 것 같습니다. 수년 동안 RDS는 InnoDB 로그 파일 크기를 조정할 수 없거나 테이블 기반 로그를 제외하고 쿼리 로그를 제공하지 못했습니다. 그것은 바뀐 것 같습니다. 그러나 나는 내가 로그인 할 수없는 데이터베이스 서버에 대한 편견을 가지고 있다고 생각한다. :-) –

    2

    나는 "당신이 뭔가 잘못하고있다"고 생각합니다. RDS 제한에 도달 한 경우는 거의 없지만 일부 제한을 두는 경우도 있습니다.

    자세한 모니터링을 시작하여 시작하십시오. 이렇게하면 제한 요소가 실제로 무엇인지 판단하는 데 도움이되는 OS 레벨 정보가 제공됩니다. 느린 쿼리 로그와 데이터베이스 통계를 살펴보면 문제를 일으키는 쿼리가있을 수 있습니다.

    잘못된 쿼리, I/O 제한 또는 다른 문제 일 수있는 문제를 이해하면 문제를 해결할 수 있습니다. RDS를 사용하면 여러 개의 읽기 복제본을 만들 수 있으므로 일부 읽기로드를 슬레이브로 이동할 수 있습니다.

    또한 Aurora로 이동하면 더 나은 I/O 성능을 얻을 수 있습니다. 또는 PIOPS를 사용하거나 더 많은 디스크를 할당하면 성능이 향상됩니다. SSD 스토리지를 사용하고 있습니까?

    다른 제안 - 위의 계산 (위의 4 단계)에 상당한 시간이 소요되는 경우 두 개 이상의 트랜잭션으로 나누는 것이 좋습니다.

    2

    query_cache_size은 50M 이상입니다. 당신은 자주 쓰고 있습니다 - 테이블 당 초당 여러 번? 즉, 변경된 테이블에 대한 항목을 제거하기 위해 QC를 여러 번/초 스캔해야합니다. 이것은 QC가 2.5GB 일 때 시스템에 큰 부하입니다!

    query_cache_type은이어야합니다. 그리고 그 경우에는 SELECTsSQL_CACHESQL_NO_CACHE으로 후춧가루를 칠하십시오.

    slowlog가 설정되어 있으므로 pt-query-digest를 사용하여 출력을보십시오. 처음 몇 가지 검색어는 무엇입니까?

    일반적인 작업에는 쓰기가 포함되므로 읽기 전용 슬레이브를 사용하는 장점이 없습니다.

    봇이 임의로 실행되고 있습니까? 또는 그들은 모두 동시에 시작합니까? (후자는 CPU 등에서 끔찍한 스파이크를 일으킬 수 있습니다.)

    "오래된"레코드는 어떻게 보관하고 있습니까? PARTITIONing과 "전송 가능 테이블 스페이스"를 사용하는 것이 가장 좋습니다. PARTITION BY RANGE과 21 개의 파티션 (두 개의 추가 기능 포함)을 사용하십시오.

    일반적인 트랜잭션이 한 행으로 작동하는 것 같습니다. 한 번에 10 개 또는 100 개로 작동하도록 수정할 수 있습니까? 100 개가 넘는 SQL Server는 비용 효율적이지 않습니다. SQL은 한 번에 많은 행을 처리하는 것보다 훨씬 효율적입니다. 우리에게 SQL을 보여라. 우리는 세부 사항을 파헤쳐 볼 수 있습니다.

    새로운 행을 삽입 한 다음이를 한 번에 업데이트하는 것이 이상하게 보입니다. 삽입을하기 전에 완전히 계산할 수 없습니까? 오랫동안 inserted_id를 매달아 놓으면 같은 일을하는 다른 사람들에게 방해가 될 수 있습니다. innodb_autoinc_lock_mode의 값은 무엇입니까?

    "사용자"가 서로 상호 작용합니까? 그렇다면 어떤 방식으로?

    관련 문제