Programing

MySQL 샤딩 접근 방식?

lottogame 2020. 9. 16. 08:20
반응형

MySQL 샤딩 접근 방식?


MySQL 테이블을 샤딩하는 가장 좋은 방법은 무엇입니까? 내가 생각할 수있는 접근 방식은 다음과 같습니다.

  1. 애플리케이션 수준 분할?
  2. MySQL 프록시 레이어에서 샤딩?
  3. 샤딩을위한 중앙 조회 서버?

이 분야에서 흥미로운 프로젝트 나 도구를 알고 있습니까?


완전히 피할 수없는 경우가 아니라면 MySQL 테이블을 분할하지 않는 가장 좋은 방법입니다.

응용 프로그램을 작성할 때 일반적으로 속도와 개발자 속도를 최대화하는 방식으로 작성하려고합니다. 필요한 경우에만 지연 시간 (답변이 준비 될 때까지의 시간) 또는 처리량 (시간 단위당 응답 수)을 최적화합니다.

이러한 모든 파티션의 합계가 더 이상 단일 데이터베이스 서버 인스턴스에 맞지 않는 경우에만 파티션을 분할 한 다음 다른 호스트 (= 샤드)에 할당합니다. 그 이유는 쓰기 또는 읽기 때문입니다.

쓰기 사례는 a) 쓰기 빈도로 인해이 서버 디스크에 영구적으로 과부하가 걸리거나 b) 너무 많은 쓰기가 진행되어이 복제 계층에서 복제가 영구적으로 지연됩니다.

샤딩의 읽기 사례는 데이터의 크기가 너무 커서 데이터의 작업 세트가 더 이상 메모리에 맞지 않고 데이터 읽기가 대부분의 시간 동안 메모리에서 제공되는 대신 디스크에 도달하기 시작하는 경우입니다.

당신이 경우에만 샤딩하는 당신은 그것을 할.


샤딩하는 순간 여러 가지 방법으로 비용을 지불하게됩니다.

대부분의 SQL은 더 이상 선언적이지 않습니다.

일반적으로 SQL에서는 원하는 데이터를 데이터베이스에 알리고 해당 사양을 데이터 액세스 프로그램으로 전환하기 위해 옵티 마이저에 맡깁니다. 유연성이 있고 이러한 데이터 액세스 프로그램을 작성하는 것은 속도에 해를 끼치는 지루한 작업이기 때문입니다.

샤딩 된 환경에서는 노드 A의 테이블을 노드 B의 데이터에 조인하거나 노드보다 큰 테이블이 노드 A와 B에 있고 노드 B와 C에있는 데이터에 대해 데이터를 조인 할 수 있습니다. 이를 해결하기 위해 (또는 MySQL 클러스터를 재창조하고 있음) 애플리케이션 측 해시 기반 조인 해결을 수동으로 작성하기 시작합니다. 즉, 더 이상 선언적이지 않지만 절차 적 방식으로 SQL 기능을 표현하는 많은 SQL로 끝납니다. (예를 들어 루프에서 SELECT 문을 사용하고 있습니다).

많은 네트워크 지연이 발생합니다.

일반적으로 SQL 쿼리는 로컬에서 확인 될 수 있으며 옵티마이 저는 로컬 디스크 액세스와 관련된 비용을 알고 이에 대한 비용을 최소화하는 방식으로 쿼리를 해결합니다.

샤딩 된 환경에서 쿼리는 네트워크를 통해 여러 노드에 대한 키-값 액세스를 실행하거나 (왕복 당 개별 키 조회가 아닌 일괄 키 액세스를 사용하여) WHERE절의 일부를 가능한 노드로 푸시 하여 해결됩니다. 적용 ( '조건 푸시 다운'이라고 함) 또는 둘 다.

그러나 최상의 경우에도 이것은 로컬 상황보다 더 많은 네트워크 왕복을 포함하며 더 복잡합니다. 특히 MySQL 옵티마이 저는 네트워크 대기 시간에 대해 전혀 알지 못하기 때문에 (예, MySQL 클러스터는 천천히 향상되고 있지만 클러스터 외부의 바닐라 MySQL의 경우 여전히 사실입니다).

SQL의 많은 표현력을 잃고 있습니다.

그다지 중요하지 않을 수 있지만 데이터 무결성을위한 외래 키 제약 조건 및 기타 SQL 메커니즘은 여러 샤드를 확장 할 수 없습니다.

MySQL에는 작동하는 비동기 쿼리를 허용하는 API가 없습니다.

동일한 유형의 데이터가 여러 노드에있는 경우 (예 : 노드 A, B 및 C의 사용자 데이터), 이러한 모든 노드에 대해 수평 쿼리를 해결해야하는 경우가 많습니다 ( "90 일 동안 로그인하지 않은 모든 사용자 계정 찾기 이상"). 데이터 액세스 시간은 여러 노드가 병렬로 요청되고 결과가 들어오는대로 집계되지 않는 한 노드 수에 따라 선형 적으로 증가합니다 ( "Map-Reduce").

이를위한 전제 조건은 비동기 통신 API이며, MySQL에는 좋은 작동 형태로 존재하지 않습니다. 대안은 시즌 패스의 세계를 방문하는 자식 프로세스의 많은 포크와 연결입니다.


샤딩을 시작하면 데이터 구조와 네트워크 토폴로지가 애플리케이션의 성능 포인트로 표시됩니다. 합리적으로 잘 수행하려면 애플리케이션이 이러한 사항을 인식해야하며 이는 실제로 애플리케이션 수준 분할 만 의미가 있음을 의미합니다.

문제는 자동 샤딩 (예 : 기본 키를 해싱하여 어떤 행이 어떤 노드로 이동하는지 결정)하거나 수동 방식으로 기능을 분할하려는 경우 ( "xyz 사용자 스토리와 관련된 테이블은 master, abc 및 def 관련 테이블은 해당 마스터로 이동합니다. ").

기능적 분할은 사용자 스토리와 관련된 모든 테이블을 로컬에서 사용할 수 있기 때문에 제대로 수행하면 대부분의 개발자에게 보이지 않는다는 이점이 있습니다. 이를 통해 가능한 한 오랫동안 선언적 SQL의 이점을 누릴 수 있으며, 네트워크 간 전송 횟수를 최소화하기 때문에 네트워크 대기 시간이 줄어 듭니다.

기능적 샤딩은 단일 테이블이 하나의 인스턴스보다 클 수 없다는 단점이 있으며 디자이너의 수동주의가 필요합니다.

기능적 샤딩은 너무 크지 않은 많은 변경으로 기존 코드베이스에 비교적 쉽게 수행 할 수 있다는 장점이 있습니다. http://Booking.com 은 지난 몇 년 동안 여러 번 해왔으며 잘 작동했습니다.


모든 것을 말하면서 귀하의 질문을 보면 귀하가 잘못된 질문을하고 있다고 믿거 나 귀하의 문제 진술을 완전히 오해하고 있습니다.


  1. 애플리케이션 레벨 분할 : dbShards는 "애플리케이션 인식 분할"을 수행하는 유일한 제품입니다. 웹 사이트에는 몇 가지 좋은 기사가 있습니다. 정의상 애플리케이션 인식 샤딩이 더 효율적일 것입니다. 응용 프로그램이 트랜잭션을 조회하거나 프록시에 의해 리디렉션되지 않고 트랜잭션과 함께 이동해야 할 위치를 정확히 알고 있다면 자체적으로 더 빠를 것입니다. 누군가가 샤딩을 조사 할 때 속도는 유일한 문제는 아니지만 주요 관심사 중 하나입니다.

  2. 어떤 사람들은 프록시로 "샤딩"하지만 내 눈에는 샤딩의 목적을 무너 뜨립니다. 다른 서버를 사용하여 트랜잭션에 데이터를 찾을 위치 또는 저장할 위치를 알려줍니다. 응용 프로그램 인식 분할을 사용하면 응용 프로그램이 자체적으로 어디로 가야하는지 알 수 있습니다. 훨씬 더 효율적입니다.

  3. 이것은 실제로 # 2와 동일합니다.


이 분야에서 흥미로운 프로젝트 나 도구를 알고 있습니까?

이 공간의 몇 가지 새로운 프로젝트 :

  • citusdata.com
  • spockproxy.sourceforge.net
  • github.com/twitter/gizzard/

Shard-Query is an OLAP based sharding solution for MySQL. It allows you to define a combination of sharded tables and unsharded tables. The unsharded tables (like lookup tables) are freely joinable to sharded tables, and sharded tables may be joined to each other as long as the tables are joined by the shard key (no cross shard or self joins that cross shard boundaries). Being an OLAP solution, Shard-Query usually has minimum response times of 100ms or less, even for simple queries so it will not work for OLTP. Shard-Query is designed for analyzing big data sets in parallel.

OLTP sharding solutions exist for MySQL as well. Closed source solutions include ScaleDB, DBShards. Open source OLTP solution include JetPants, Cubrid or Flock/Gizzard (Twitter infrastructure).


Application level of course.

Best approach I've ever red I've found in this book

High Performance MySQL http://www.amazon.com/High-Performance-MySQL-Jeremy-Zawodny/dp/0596003064

Short description: you could split your data in many parts and store ~50 part on each server. It will help you to avoid the second biggest problem of sharding - rebalancing. Just move some of them to the new server and everything will be fine :)

I strongly recommend you to buy it and read "mysql scaling" part.


As of 2018, there seems to be a MySql-native solution to that. There are actually at least 2 - InnoDB Cluster and NDB Cluster(there is a commercial and a community version of it).

Since most people who use MySql community edition are more familiar with InnoDB engine, this is what should be explored as a first priority. It supports replication and partitioning/sharding out of the box and is based on MySql Router for different routing/load-balancing options.

The syntax for your tables creation would need to change, for example:

    CREATE TABLE t1 (col1 INT, col2 CHAR(5), col3 DATETIME) PARTITION BY HASH ( YEAR(col3) );

(this is only one of four partitioning types)

One very important limitation:

InnoDB foreign keys and MySQL partitioning are not compatible. Partitioned InnoDB tables cannot have foreign key references, nor can they have columns referenced by foreign keys. InnoDB tables which have or which are referenced by foreign keys cannot be partitioned.

참고URL : https://stackoverflow.com/questions/5541421/mysql-sharding-approaches

반응형