나그네소

TIDB 본문

sunjesoft/Goldilocks Extern DB

TIDB

나그네소티 2019. 1. 30. 14:51
<< New SQL Open Source DB >>

<< 참고 Link >>

<< TIDB 소개 >>
TIDB는  오픈 소스 분산 확장형 하이브리드 처리 및 분석 처리 데이터베이스 입니다. 
수평 확장성 및 지속성, 높은 가용성을 지원한다.(ACID)
TIDB는 Mysql 호환 되면 OLTP 및 OLAP 작업 부하를 처리 하는 원스톱 데이터워어 하우스
역을을 한다.

[특징]
* Horizontal scalability
TIDB는 새로운 노드를 추가 함으로써 수평 확장성을 제공한다. 인프라 용량에 대하여 걱정하지 마라.

* MySQL compatibility
대부분의 경우 단일 코드 라인을 변경 하지 않고도 MySQL을 TiDB로 쉽게 대체하여 어플리케이션에
전력을 공급 할 수 있으며 Mysql 에코 시스템의 헤텍을 누릴 수 있다.

* Distributed transaction
TIDB는 ACID 보장하며, 너의 데이터는 언제 어디서는 정확하고 신뢰 할 수 있을 것이다.

* Cloud Native
TiDB는 public,privite,or 병렬 작업 개발 및 공급이 클라우드 환경에서 작동 하도록 설계 되었다.
그리고 유지보수가 간단하다.

* No more ETL
TiDB는 하이브리드 OLTP/OLAP 아키텍처 이므로 더이상 ETL이 필요하지 않다 더쉽고 빠르게 사용자를 위한 새로운
가치를 창충 할 수 있다.

* High availability
너의 데이터 및 어플리케이션은 항상 켜져 있으며 지속적으로 이용이 가능하다. 

TIDB는 OLTP 및 OLAP 시나리오를 지원 하도록 설계 되었다. 

<< Tidb 기술 >>
1. Data Storage
[Foreword]
데이터베이스, 운영 체제 및 컴파일러는 3대 시스템으로 알려져 있으며 전체 컴퓨터 소프트웨어의 기초로 간주 됩니다.
데이터베이스는 비즈니스를 지원하며 어플리케이션 게층에 더 가깝다. 수십년의 발전을 거져 이분야에서 발전이 계속 되고 있다.
많은 사람들이 다른 종류의 데이터베이스를 사용해야 한다. 그리고 분산 데이터베이스 개발 경험이 있는 사람은 적다.
데이터베이스 구현의 원친과 세부 사항을 알면 자신의 기술 수준을 향상 시키는데 도움이 되며, 데이터베이스를 만들고 사용하는데
도움이 된다.
나는 기술에 종사하는 가장 좋은 방법은 오픈 소스 프로젝특에 깊이 참여 하는 것이라 믿는다. 데이터베이스도 예외가 아니다.
독적형 데이터베이스 분야에는 많은 훌륭한 오픈 소스 프로젝트가 있습니다. 
그중 Mysql 과 PostgreSQL이 가장 유명하며 많은 사람들이 소스 코드를 읽고 있다. 그러나 분산 데이터베이스의 경우, 좋은 오픈
소스 프로젝트가 많지 않다. 그리고 TiDB는 소수중 하나이다. 많은 사람들은,  특히 기술 자들은, 이 프로젝트에 참여 하기를 희망한다.
그러나 분산형 데이터베이스의 복장성 때문에 많은 사람들이 전체 프로젝트를 이해 하기가 어렵다.

[Storing Data]
데이터베이스를 저장하는 기장 기본적인 기능 부터 시작 하겠습니다. 데이터를 저장하는데 여러 가지 방법이 있으며 가장 쉬운 방법은
사용자가 보낸 데이터를 저장하기 위해 메모리에 데이터 구조를 만드는 것입니다. 예를 들면, 배열을 사용하여 데이터를 저장하고
데이터를 수힌 할 때 배열에 새항목을 추가한다. 이 솔루션은 간단하하고 기본 요규 사항을 충족 하며 우수한 성능을 제공 합니다.
그러나 그것의 결정이 장점을 능가한다. 그리고 가장 큰 문제는 모든 데이터를 메모리에 저장한다는 것이다. 그러므로 서버가 중지
되거나 다시 시작된다면 데이터가 손실 된다. 데이터의 지속성을 달성하기 위해 예를 들면 비 휘발성 저장 매체에 데이터를 저장 할 수 
있다. 우리는 디스크에 파일을 만들고 데이터를 받을 때 파일에 새 레코드를 추가 한다. 이것은 내구성 있는 저장소 솔루 션이다.
그러나 이것으로 충분치 않다. 디스크가 고장난 경우 어떻게 해야 합니까? 디스크의 불량 트랙을 피하기 위해 독립형 디스크에 RAID
구성 하여 사용 할 수 있다. 그러나 전체 기계가 다운 된다면 ? RAID는 안전하지 않다. 또다른 솔루션은 저장 및 복제를 위해 네터워크로 
데이터를 저장 하는 하드웨어 또는 소프트웨어를 사용 하는 것입니다. 그러나 문제는 복제본 간의 일관성을 보장 하는 방법입니다.
데이터의 무결성과 정확성을 확보하는 것이 기본 요구 사항 입니다. 
다음과 같은 문제들의 훨씬 더 까다로와 진다.

* 데이터베이스가 다중 데이터 센터의 재해 복구를 지원 합니까?
* 쓰기 속도가 충분히 빠릅니까?
* 데이터가 저장 될 때 데이터를 읽는 것이 편리 합니까?
* 저장된 데이터를 업데이트 하는 방법 ? 동시에 revision(record/mvcc)를 어떻게 처리 합니까?
* atomically 여러개 레코드를 수정 하는 방법?

이 모든 문제를 해결 하기가 어ek렵다. 그러나 우수한 데이터베이스 스토리지 시스템은 각각의 모든 것을 처리 할 수 있어야 한다.
이것을 위해, 우리는 TiKV를 개발 하였다.
TiKV에 대해 이야기 할 때 SQL에 대한 개념은 잊어 버리고 성능과 안정성이 뛰어난 거대한 분산 형 Order Map인 TiKV를 구현 하는
방법에 중점을 두시기 바랍니다.

[Key-Value]
데이터 저장 시스템은 무엇보다 데이터 저장 모델을 결정해야 합니다. 즉, 데이터를 저장하는 포맷. TiKV는 Key-Value 모델을
선택하고 순서대로 트래버스 하는 솔루션을 제공 합니다. 간달히 말하면 : 키와값이 원본 바이트 배열 인 거대한 Map으로 TiKV를
볼수 있다. 이 Map에서, Key는 바이트 배열의 원시 이진 비트에 따라 비교 순서로 정렬 됩니다.

다음 사항을 염두해 두어야 한다.
- 이것은 Key-Value 쌍에대한 거대한 지도이다.
- 이지도의 Key-Value 쌍은 키의 이진 시퀀스따라 정렬 됩니다. 우리는 키의 위치를 찾고 다른 Key-Value 쌍에 Next 메서드를 사용 할 
  수 있으며 이 Key-Value 쌍은 모두 이 값보다 큽니다.

내가 말하는 스토리지 모델과 SQL의 테이블 사이의 관계를 궁금해 할 것입니다. 여기에서 나는 강조하고 싶다 : 그들은 무의미하다.

[RocksDB]
내구성 스토리지 엔진은 디스크에 데이터를 저장하고 TiKV도 예외는 아닙니다. 그러나 TiKV는 디스크에 바로 데이터를 쓰지 않는다.
대신에,  Rock DB에 데이터를 저장한 다음 RocksDB가 데이터 저장을 담당합니다. 그 이유는 독립형 스토리지 엔진, 특히 고성능 독립형
엔진을 개발하는데 많은 비용이 소요되기 때문입니다. 당신은 모든 종류의 자세한 옵티마이제이션을 필요로 한다. 다행스럽게도 RocksDB는
우리의 모든 요구 사항족시키는 뛰어난 오픈 소스 독립형 스토리지 엔진이라는 것을 알게 되었습니다.
게다가 페이스북 팀이 최적화를 유지함에 따라 많은 노력을 기울이지 않고도 강력하고 발전하는 독립형 엔진을 즐길 수 있습니다.
그러나 우리는 RocksDB에 몇 줄의 코드를 제공합니다. 이 프로젝트가 더 잘 진행 되기를 바랍니다.
RocksDB를 독립형 키-값 맵으로 간주 할 수 있습니다.

[Raft]
효과적이고 안정적인 로컬 스토리지 솔루션을 찾는 것이 전체 구현의 중요한 첫 번째 단계이다. 이제는 더 어려운 문제에 직면해 있습니다.
단일 시스템이 고장 났을 때 데이터의 손상과 정확성를 확보하는 방법은 무엇입니까? 좋은 방법은 데이터를 여러개의 머신으로 복제 하는 
것입니다. 그런다음 한 대의 컴퓨터가 고장나면, 우리는 다른 기계에 복제본을 가지고 있습니다. 그러나 복제 솔루션은 신뢰할 수 있고 
효과적이어야 하며 유효하지 않은 복제본의 상황을 처리 할 수 있어야 합니다. 그것은 어렵지만 Raft로 만든멸 가능 하다.
Raft는 컨센서스 알고리즘이며 Paxos와 동급이며 Raft는 이해하기 쉽습니다.

우리는 Raft을 구현하기 위해 수많은 최적화 작업을 수행 했으며 자세한 내용은 수석 설계자인 Tang LIu가 작성한 이 블로그를 참조하십시요.

Raft는 컨세서스 알고리즘이며 세가지 중요한 기능을 제공 한다. 

- Leader election (지도자 선출)
- Membership change (회원 변경)
- Log replicaiton  (로그 복제)

TiKV는 Raft를 사용하여 데이터를 복제하고 각 데이터 변경 사항은 Raft 로그로 기록 됩니다.
Raft 로그 복제 기능을 통해 데이터는 안전하고 신뢰성 있게 Raft 그룹의 여러 노드와 동기화가 된다. 


요약 하자면, 스탠다드 RockDB를 통하여, 우리는 디스크에 데이터를 빠르게 저장 할 수 있다.
Raft을 통하여 우리는 기계 고장시 여러 대의 기계로 데이터를 복제 할 수 있다.
데이터는 RocksDB가 아닌 Raft의 인터페이스를 통해 기록 됩니다. Raft의 구현 덕분에, 우리는
분산 Key-value를 가지면 더 이상 기계 고장에 대하여 걱정할 필요가 없다.

[Region]
이 장에서 매우 중요한 개념을 소개 하려고 합니다. 일련의 메커리즘을 이해하는 기초 입니다.
시작하기 전에, Raft에 대해 잊어 버리고 모든 데이터가 하나의 복제본만 가지고 있다고 본다.
앞서 언급했듯이, TiKv는 거대한 주문 Key-Value Map으로 되어 있다고 간주한다.
스토리지의 수평 확장성을 구현 하기 위해, 우리는 여러 대의 컴퓨터에 데이터를 배포해야 합니다.
Key-Value 시스템의 경우 여러대의 컴퓨터 머신에 데이터를 배포하는 2가지 대표적인 솔루션이 있다.
하나는 해시를 만드는 것이다 그리고 해시 값에 따라 스토리지 노드를 선택 합니다.
다른 하나는 Rang를 사용 하고 스토리지 노드에 시리얼 키의 세그먼트를 저장 하는 것입니다.
TiKV는 두 번째 솔루션을 선택 하고 전체 Key-Value 공간을 여러 세그먼트로 나누었습니다.
각각의 세그먼트는 일련의 인접한 키로 구성되며 이런한 세그먼트를 "Region" 이라고 부릅니다.
데이터를 저장할 각 Region의 크기 제한이 있습니다.(기본값은 64M이며 크기를 조정할 수 있다.)
각 Region은 Startkey에서 EndKey까지의 왼쪽-종료-오른쪽-오픈 간격으로 설명 할 수 있습니다.


내가 말하는 Region은 SQL의 테이블과 아무런 관련이 없음을 상기하십시오. 지금은 SQL을 잊고 Key-Value에 집중하십시요.
데이터를 Region으로 나눈 후, 우리는 두개의 작업을 이행 할 것이다.
- 클러스터의 모든 노드에 데이터를 배포하고 Region을 데이터 이동의 기본 단위로 사용 합니다. 또한 각 노드의 REgion
  수는 대략 동일해야 한다.
- Region 내 Raft 복제 및 회원 관리.

이 두가지 작업은 매우 중요 하며 그리고 나는 하나씩 차례로 볼것이다.

첫번째 과제는, 데이터는 Key 따라 여러 Region으로 분할되고 각 Region의 모든 데이터는 하나의 노드에 저장됩니다.
우리 시스템의 한 구성 요소를 클러스터 구성의 모든 노드에 Region을 고르게 분배할 책임이 있습니다.
이것은, 한편으로는, 스토리지 용량의 수평 확장을 구현한다.
(언젠가 새로운 노드가 추가 되면 시스템은 다른 노드의 Region을 자동으로 스케쥴링 할 것이다.)
동시에, 상위 클라이언트가 필요한 데이터에 액세스 할 수 있도록 보장하기 위해, 다른 구성 요소는 노드 사이의 Region의
분포를 기록합니다. 다른 말로, 너는 키의 정확한 Region의 쿼리를 할 수 있다. 그리고 그 Region의 Node는 Key를 통하여 배치된다.

두번째 작업으로 이동 하자. TiKV Region 안의 데이터를 복제한다. 이는 하나의 Region의 데이터 "복제본" 이라는 이름을 가진
여러 복제본을 갖게 됨을 의미합니다. Raft는 복제본 간의 데이터 일관성을 유지하는데 사용 됩니다.
한 Region의 여러 복제본은 다른 노드에 저장되며, Raft Group으로 구성 된다. 한 복제본은 그룹의 리더 역할을 하고 다른 복제본은
추종자 역할을 합니다. 모든 읽기와 쓰기는 리더를 통해 수행되고 리더는 팔로어에게 복제 됩니다.

다음 다이어그램은 지역 및 Raft Group에 대한 전체 그림을 보여 줍니다.

우리가 Region에서 데이터를 배포하고 복제 할 때, 우리는 어느 정도까지 재난 복구 능력을 가진 분산 Key-Value 시스템을 가지고 있다.
너는 더 이상 용량에 및 디스크 고장 시 데이터 손실에 대하여 걱정할 필요 없다. 이것은 완벽하지 않다. 우리는 더 많은 기능이 필요하다.

[MVCC]
많은 데이터베이스가 다중 버전 동시성 제어를 구현 합니다.(MVCC) 그리고 TiKV도 예외가 아니다. 
두 클라이언트가 MVCC 없이 key value 업데이터르 한다고 가정 한면 데이터가 잠길 것이다. 
분산 시나리오에서, 이로 인해 성능 및 교착 상태가 발생 한다.
TiKV는 Key에 version을 추가하여 mvcc를 구현 하였다. TiKV의 데이터 레이아웃은 다음과 같이 볼 수 있습니다.

~~ Key1 -> Value
~~ Key2 -> Value
~~ ……
~~ KeyN -> Value

MVCC에서 TiKv의 Key 배열은 다음과 같습니다.

~~ Key1-Version3 -> Value
~~ Key1-Version2 -> Value
~~ Key1-Version1 -> Value
~~ ……
~~ Key2-Version4 -> Value
~~ Key2-Version3 -> Value
~~ Key2-Version2 -> Value
~~ Key2-Version1 -> Value
~~ ……
~~ KeyN-Version2 -> Value
~~ KeyN-Version1 -> Value
~~ ……

Key의 여러 버전에 대해서 우리는 더 큰 수자를 먼저 쓴다. 이런 방법으로, 사용자 Key + 값으로 업드면,
그는 Key version으로 Mvcc의 키를 만들 수 있다. 
그는 직접 key-version을 볼 수 있다. 그리고 Key-version 보다 크거나 같거나 또는 처음 위치를 찾을 수 있다. 

[Transaction]
TiKV의 처리는 퍼콜 레이터 모델을 체택 하고 많은 최적화를 하였다. 
내가 말하고 싶은 것은 TiKV의 트랜젝션은 optimisitc lock 사용한다는 것이다. 실행 프로세스중에 쓰기 충동을
감지 하지 못합니다. 오직 커밋 단계에서만 충돌이 날 것이다. 이전 커밋을 완료한 트랙젼션은 성공적으로 기록되고
다른 트랜잭션도 성공적으로 기록된다. 비즈니스의 쓰기 충돌이 심하지 않다면 이 모델에서의 성능을 좋다.
예를 들면, 큰 테이블에서 데이터의 일부 행을 무작위로 업데이트 하는데 효과적이다. 그러나 쓰기 충돌이 발생 한다면
성능은 좋지 않을 것이다. 많은 클라이언트가 동시에 몇 행을 Update 하는 상황은 심각한 문제를 초래 한다.

- 참고 : 낙관적 잠금(Optimistic locking)
낙관적인 잠금은 레코드를 업데이트 할때에 버전을 보고, 충돌나면 그 에러를 처리하고, 충돌나지
않으면 그냥 업데이트 한다.  비관적인 잠금은 레코드를 갱신하는 동시에 해당 컬럼을 잠그고, 트랜
잭션이 커밋되면 잠금을 푼다.

낙관적이라함은... 하면하고 말면 말고 이런거고,,비관적이라함은... 충돌할테니 먼저 잠그는 그런느낌...

왠지 데자뷰가 떠오른다..낙관적인 자신감, 비관적인 자괴감.. 아무튼..

Pessimistic Locking 은 비관적 잠금, Optimistic Locking 은 낙관적인 잠금으로 보통 번역된다. 저 두
가지의 용어가 쓰이는 경우는 보통 Multi-User, Multi-Transaction 상황에서 쓰이곤 한다.
두 가지의 용어가 어떠한 차이점을 갖는 지 다음의 경우를 생각해보자.


User1, User2 가 동시에 Table1의 Record1을 동시에 Update하는 상황을 가정하자.

1. Locking이 없는 경우
- User1이 Record1을 읽는다.(read)
- User2가 Record1을 읽는다.(read)
- User1이 Record1을 수정한다.(update)
- User2가 Record1을 수정한다.(update)
User2는 User1의 수정이 끝나기 전 데이터를 읽어들였기 때문에 최종적으로는 User1의 update는
무시되고 User2의 update만 남게된다. 이런 경우를 lost update라고 부른다.

2. Pessimistic Locking의 경우
- User1이 Record1을 읽고 있는 동안 해당 record에 lock을 걸어둔다.(update 때문에)
- User2가 Record1를 읽으려고 시도하지만 lock이 걸려있기 때문에 User1의 Update가 수행이 완료될 때 까지 기다린다.
- User1이 Record1을 수정한다.(update)
- User2는 이제 Record1을 읽을 수 있고 User1의 Update가 이루어진 데이터를 읽을 수 있다.
- User2가 Record1을 수정한다.(update)
이로써 lost update문제는 해결된다. 이와 같은 방식의 문제는 동시성(concurrency)이다. User1의
데이터 update 작업이 끝나지 않으면 User2는 Record1을 읽을 수 조차 없다. 이러한 접근법은 실제로는 구현된 적은 없다.


3. Optimistic Locking의 경우
- User1이 Record1을 읽는다. (read) 그와 동시에 timestamp(1)를 남긴다.
- User2가 Record1을 읽는다. (read) 그와 동시에 timestamp(1)를 남긴다.
- User1이 Record1을 수정하려고 시도한다.(update). timestamp(1)이 데이터 베이스의 timestamp(2)와 일치한다.
  따라서 데이터 수정 작업을 수행하고 timestamp(1)을 timestamp(2)로 수정한다.
- User2가 Record2를 수정하려고 시도한다.(update). User2가 가지고 있는 timestamp(1)을 현재 데이터베이스의
  timestamp(2)와 일치하지 않는다. 따라서 error를 리턴받는다. timestamp가 일치하지 않는 다는 error를 리턴받은
  후 User2는 반드시 Record1을 다시 읽어서(re-read) User1이 변경했던 데이터와 timestamp의 변경사항을 읽어들인다.
  그 후에 다시 update를 재시도 한다.(re-update)

다시 생각해보면 비관적인 잠금(Pessimistaic Locking) 말그대로 동시에 데이터 수정 작업이 진행될 경우를 가정하고,
아예 데이터가 꼬이는 것을 방지한다. 마치 “이 데이터는 다른 사람이 수정할 지도 몰라. 그러니깐 반드시 잠궈놔야 해”
라고 접근하는 방식이라 비관적인 방식인 것이다. 반대로 낙관적인 잠금(Optimistic Locking)의 경우는 “이 데이터가
혹시 꼬일지라도 일단은 다 update하는 게 맞아. 혹시 동시에 작업이 수행되면 User에게 노티해주지 뭐..”라고 접금하는
방식이기에 낙관적인 방식인 것이다.

* 요즘은 대부분의 ejb에서 지원을 해줘서 사용하기 편리하다..(optimistic locking)
toplink, eclipselink, hibernate 등에서 테이블 및 model java생성시 optimistic lock 체크하는 부분을 설정하면
테이블에 version 컬럼을 이용해 int값으로 한 객체에 해당하는 row의 충돌여부를 인식해서 잠금기능을 해준다.. 대단하다.
따라서 트랜잭션 발생시 세션 혹은 unitofwork의 version이 최신 version과 맞을 때만 commit되도록 하여 데이터가 동시에
수정되는 현상을 방지할수있겠따, 물론 version은 int말고도 timestamp로도 가능


[Miscellaneous]
지금까지, 나는 TiKV 기본 컨셉 및 세부사항에 대하여 설명 하였고 이 분산 및 트랜잭션 Key-Value 엔진의 계층화 된 구조 및
다중 데이터 센터 재해 복구 구현 방법에 대해 설명 하였다. 

2. Copmputing
나의 마지막 블로그는 TiDB가 데이터를 저장하는 방식을 소개 합니다. 또한 TiKV의 기본 개념이기도 합니다. 이 기사는,
TiDB가 어떻게 데이터를 저장하기 위해 최하위 계층 키-값을 사용하는지에 대해 자세히 설명 할 것입니다.
관계형 모델을 키-값 모델에 맵핑하고 sql 컴퓨팅을 수행 합니다.

[Mapping the Relational Model to the Key-Value Model]
관계형 모델을 단순한 테이블 및 SQL 문으로 단순화 합시다. 우리가 생각해야 할 것은 테이블을 저장하고 key-value 구조
위에 SQL문을 실행하는 방법입니다. 

다음과 같은 표가 있다고 가정합시다:

CREATE TABLE User 
{
    ID int,
    Name varchar(20),
    Role varchar(20),
    Age int,
    PRIMARY KEY (ID),
    Key idxAge (age)
};

SQL 과 Key-VAlue 구조 사이의 큰 차이점을 감안할 때 SQL을 key-value에 편리하고 효율적으로 매핑하는 방법은
매우 중요 합니다. 기사는 가장먼저, 데이터 컴퓨팅의 요구 사항 및 특징을 살펴보고, 이것은 매핑 솔루션이 좋은지
아닌지를 경정하는데 필수적입니다.

테이블에는 세 부분의 데이터가 있습니다.
- 테이블의 메타데이터
- 테이블의 행
- 인덱스 데이터

이 기사는 메타데이터데 대해 설명하지 않습니다.

데이터는 행이나 열에 저장 될 수 있으며 둘 다 장점과 단점이 있습니다. 
TiDB의 기본 목표는 온라인 트랜잭션 처리(OLTP) 입니다. OLTP는 한행의 데이터를 신속하게 읽고, 저장하고, 엽데이트 하고 삭제 합니다. 
그러므로 행 저장소가 더 좋습니다.

TiDB는 Primary index 와 secondary index 지원한다. index 깆능은 더 빠른 쿼리, 높은 쿼리 성능 및 제약 조건을 위한 것입니다.

두 가지 형식의 쿼리가 있다.
* Point Query , 쿼리에 대해 Pimary Key, Unique Key 같은 조건을 사용 하는 경우,
  ex: select name from user where id=1;, 인덱스를 통해 틍정행의 데이터를 찾습니다.

* Range Query, ex :  select name from user where age > 30 and age < 35;,
  IndexAge 통해 나이가 20에서 30사이인 데이터를 쿼리 합니다. 인덱스의 두가지 타입:
  unique index 와 non-unique index 둘다  TiDB에서는 지원된다.

저장 될 데이터의 특징을 분석 후, Insert/Upate/Delete/Select 문을 포함하여 데이터를 조작하기 위해 수행해야 하는 작업으로
넘어 갑니다.

* Insert 문은 Row를 Key-Value에 쓰고 인덱스 데이터를 만듭니다.
* Update 문은 필요한 경우 Row 및 Index Data를 업데이트 합니다.
* Delete 문은 Row 및 Index 삭제한다.
* 4가지중, select 문장은 가장 복잡한 상황을 처리 한다.
  * 한줄의 데이터를 쉽고 빠르게 읽는다. 이 경우 각 행에는 ID(명시적 또는 암시적)가 있어야 합니다.
  * 연속적으로 여러 행을 읽는다. (select * from user;)
  * 인덱스를 통한 데이터 읽기, point Query 또는 Range Query에서 인덱스를 활용한다.

 
global로 수행 및 분산 key-value 엔진이 위의 요구 사항을 충족 시킵니다.
global 수행 시 기능은 몇가지 문제를 해결하는데 도움이 된다.

두가지 예를 들면 다음과 같다:
* 데이터의 행을 빠르게 얻을 수 있다. 특정 또는 일부 키를 만들 수 있다고 가정 합니다.
  이 행을 찾으면 TiKV에서 제공하는 Seek 메서드를 사용하여 이 데이터 행을 빠르게 찾을 수 있습니다.

* 전체 테이블 스캔한다. 
  데이블을 키 범위에 매핑 할 수 있으면 StartKey에서 EndKey까지 스캔하여 모든 데이터를 가져올 수 있습니다. 인덱스 데이터를
  조작하는 방법은 비슷합니다.

TiDB에서 이 작업이 어떻게 동작하는지 보자.

TiDB는 각각의 테이블에 TableID을 할당한다, 각각의 Index에는 IndexID, 그리고 각각의 Row에는 RowID.
테이블에 Integer Primary Key을 가지고 있다면, 이 값은 RowID 사용 될 것이다. TableID는 전체 클러스터에서
고유하며 IndexID/RowID는 테이블에서 고유하다. 이 ID는 모두 int64이다.
각 데이터 행은 다음 규칙에 따라 key-value 쌍으로 인코딩 됩니다.

Key: tablePrefix_rowPrefix_tableID_rowID
Value: [col1, col2, col3, col4]

Key의 tablePrifix/rowPrefix는 특정 문자열 상수이며 Key-Value 공간에서 다른 데이터를 구별하는데 사용 됩니다.
인덱스 데이터는 다음 규칙에 따라 key-value으로 인코딩 됩니다.:Key:
tablePrefix_idxPrefix_tableID_indexID_indexColumnsValue Value: rowID

위의 인코딩 규칙은 고유 인덱스에 적용 되지만 고유하지 않은 인덱스에 대해서는 고유 키를 생성 할 수 없습니다.
그 이유는 인텍스의  tablePrefix_idxPrefix_tableID_indexID_ 가 동일하기 때문이다.
따라서, 우리는 non-unique index를 인코딩하기 위해 몇가지 변경을 했습니다.

Key: tablePrefix_idxPrefix_tableID_indexID_ColumnsValue_rowID
Value:null

이 방법은, 각 데이터 행의 고유키를 작성 할 수 있다. 위의 규칙에서, 
Key의 모든 xxPrefix는 다른 유형의 데이터 간의 충동을 피하기 위해 네임스페이스를 구별하는 기능이 있는 문자열 상수 입니다.

var(
tablePrefix = []byte{'t'}
recordPrefixSep = []byte("_r")
indexPrefixSep = []byte("_i")
)

행 또는 Index Key  인코딩 솔루션에는 동일한 접두사가 있습니다.
특히 테이블의 모든 행은 동일한 접두사를 가지고 있고 인덱스의 데이터도 마찬가지이다,
동일한 prefix 가진 데이터는 TiKV의 key 공간에 함께 정렬 된다. 다른 말로,  우리는 신중하게 접미어의 인코딩 솔루션을
설계해야 한다. 계속되는 비교 관계는 변함이 없다. 행 또는 인덱스 데이터는 순서대로 TiKV에 저장 될 수 있다.
인코딩 전후에 관계를 유지하는 솔루션을 Memcomparable이라고 합니다. 모든 유형의 가치에 대해서는, 인코딩 전의 2개의 객체의
비교 결과는  encode 후의 바이트 배열의 결과 와 일치합니다.
이 인코딩 솔루션을 채택할 때 테이블의 모든 행 데이터는 Rowid 순서에 따라 TiKv의 공간에 정렬 됩니다.
인덱스의 ColumnValue 순서에 따라 특정 인덱스의 데이터도 마찬가지 입니다.

이제 이전 요구 사항과 TiDB의 매핑 솔루션을 고려하여 솔루션의 실현 가능성을 검증 합니다.
- 첫째로, 매핑 솔루션을 통해 Row 및 Index 데이터를 Key-Value 데이터로 변환하고 각 행과 각 인덱스 데이터에 고유한 Key가 
  있는지 확인 합니다.
- 두번째로, 우리는 Point query 와 Range  Query 모두 적합하므로 이 매핑 솔루션을 사용하여 일부 행 또는 해당 Index 입력해
  해당 하는 key를 쉽게 만들 수 있습니다.
- 마지막, 테이블 제약 조건을 설절 할 때, 우리는 생성하고 해당 제약이 만족되었는지 여부를 결정하는 특정 Key 존재를 확인 할수
  있습니다.

지금까지, 우리는 테이블 key-value에 매핑하는 방법을 다루었습니다. 여기에 동일한 테이블 구조를 가진 사례가 하나 더 있습니다.
테이블에 3개의 데이터 행이 있다고 가정하자.

1, "TiDB", "SQL Layer", 10
2, "TiKV", "KV Engine", 20
3, "PD", "Manager", 30

첫번째, 각 데이터의 Row는 Key-Value 맵핑되었을 것이다. 이 테이블에는 int 기본 키가 있으므로 rowid 값이 이 기본 키의 값입니다.
이 테이블의 TableID가 10이고 다음과 같다고 가정합니다.
t_r_10_1 --> ["TiDB", "SQL Layer", 10]
t_r_10_2 --> ["TiKV", "KV Engine", 20]
t_r_10_3 --> ["PD", "Manager", 30]

Primary Key외에 이 테이블에 Index가 있다. index id가 1이라고 가정하면 그 데이터는 다음과 같습니다.

t_i_10_1_10_1 —> null
t_i_10_1_20_2 --> null
t_i_10_1_30_3 --> null

이전 인코딩 규칙은 위의 예를 이해 하는데 도움이 됩니다.

[MetaData Management]
테이블의 데이터와 인덱스 key-value 매핑 되는 방법을 설명 한 후, 이 장은 metadata 저장에 대하여 소개한다.

데이터베이스와 테이블 모두 메타 데이터를 가지며, 정의된 다양한 속성을 참조한다. 이 모든 정보는 TiKV에 지속적으로 저장
되어야 한다. 각각의 데이터베이스/테이블은 unique ID를 가지며 ID는 quique 식벽자로 사용 된다.
Key-Value로 인코딩 할 때 이ID는 Key로 인코딩되며 접두사는 m_입니다. 이 방법으로 키가 생성되고 해당 값을 직렬화 된 메타 
데이터를 저장합니다.

이와 별개로, 특수 kye-value는 현재 스키마 정보의 버전을 저장한다. TiDB는 google f1의 온라인 스키마 변경 알고리즘을 
사용한다. 백그라운드 스레는는 TiKV에 저장된 스키마 버전이 변경 되었는지 지속 적으로 체크한다.

[Architecture of SQL on Key-Value]
다음 다이어그램은 TiDB의 전체 아키텍처를 보여준다.:

TiKV 클러스터의 주요 기능은 데이터를 저장하는 Key-Value 엔진 이다. 마직막 컬럼을 철저히 소개한다.
이 기사에서는 SQL 계층, 즉 TiDB 서버에 중점을 둡니다.
이 계층의 노드는 비 저장 노드이며, 데이터를 저장 하지 않고, 그리고 각각은 완전히 동등하다.
TiDB Server는 사용자 요청을 처리하고 SQL 연산 로직을 실행 합니다.


[SQL Computing]
SQL에서 key-value 로의 맴핑 솔루션은 관계형 데이터를 저장하는 방법을 보여 줍니다. 이 데이터를 사용하여 쿼리
요청을 충족하는 방법을 이해해야 합니다. 그리고, 다른 말로, 쿼리문의 맨 아래 계층에 저장된 데이터에 액세스 하는 방법.
가장 쉬운 방법은 내가 소개한 매핑 솔루션을 통해 SQL 쿼리를 키-값 쿼리에 매핑하는 것입니다. 그런 다음 모든 종류의 작업을
실행하기 전에 키-값 인터페이스를 통해 해당 데이터를 가져 옵니다.
As for the statement Select count(*) from user where name="TiDB";
우리는 테이블의 모든 데이터를 읽고 이름 필드가 TiDB인지 확인해야 합니다. 그렇다면 이 행을 반환한다.
작업이 다음 key-vlua 작업 프로세스로 전송 됩니다.

* Create Key Range: Table의 모든 RowsID는 [0,MaxInt64] 범위 안에 있다, 0과 MaxInt64 및 Row의 Key 인코딩 규칙을 사용하여
  왼쪽-닫음 오른쪽-열림 간격[StartKey,EndKey]을 만든다.

* Scan Key Range: 이전에 생성 된 키 범위에 따라 TiKv에서 데이터를 읽는다.

* Filter the data: 각각의 데이터 행을 읽을 때 name="TiDB" 표현을 평가한다. 만약 결과가 참이라면 이 행을 반환한다. 만약 거짓
  이라면 이 행을 SKIP한다.

* Evaluate Count: 요구 사항을 충족시키는 각 행에 대해 Count 값을 더하다.

woong : 
step1. TiDB에서 start key, end key 만든다.
step2. start key 따라 데이터를 읽는다.
step3. 가져온 데이터의 행을 읽고 name="TIDB" 만 참이라고 행을 반환 
step4. count() 행을 더한다.

프로세스에 대한 다음 다이어그램을 참조하십시오:



이 솔루션은 여전희 다음과 같은 단점이 있지만 작동합니다.

- 데이터를 스캔 할 때 각 행은 key-value 연산을 통해 TiKV에서 읽어야 합니다. 그러므로, 최소한 하나의 PRC 오버헤드가 있다.
  많은 양의 데이터를 스캔하는 경우 오버헤드 커진다.

- 모든행에 적용 할 수 없다. 조건을 충족 시키지 않는 데이터는 읽을 필요가 없습니다.

- 조건을 만족시키는 행의 값은 의미가 없습니다. 여기에서 필요 한것은 단지 행의 수입니다.

woong : 단점
범위 연산의 경우 TiKV에서 하나씩 모든 Rows를 가져와 처리 해야 하기 때문에 RPC가 발생한다.
이리하면 부하가 많을 것으로 보인다. (아래에서 단점을 제거 했다.)
참고 : RPC(Remote Procedure Call) 원격 프로시저를 Call 한다는 의미이다.


[Distributed SQL Operation]
위의 단점을 피하는 것은 심플하다. 

- 첫번째, 우리는 막대한 RPC 호출을 막기 위해 스토리지 노드 가까이에서 조작이 필요하다.
- 그런다음 필터를 스토리지 노드로 푸시 다운 해야 합니다. 이 경우, 유효한 행만 리턴 될 것이다 그리고 무의미한 네트워크
  전송은 피할 수 있다.
- 마지막으로, 우리는 사전 집계를 위해 aggregate function 및 group by를 푸시 다운 할 수 있다.
  각 노드는 하나의 카운트 값을 반환하며 TiDB-server가 모든 값을 합산 합니다.

다음의 스케치는 데이터가 레이어별로 어떻게 반환 되는지 보여준다.


woong : 우리 Cluster SQL 전달 방식과 동일 하다. Storage에서 TiDB를 Start 하고 여러개의 TiKV
가 있을 경우 SQL를 전송 해당 조건 및 Count 결과값만을 가지고 와 TiDB에 전달 한다.


[Architecture of the SQL Layer]
이전 절에서는 SQL 계층의 일부 기능을 소개하고 SQL 문을 처리하는 방법에 대한 기본 개념을 갖기를 바랍니다. 
사실은, TiDB의 계층은 매우 복잡하고 많은 모듈과 레이어를 가지고 있습니다.
다음 다이어 그램은 모든 중요한 모듈과 호출 관계를 나열 합니다.



SQL의 요청은 TiDB-Server에 직접 또는 로드 밸런서를 통해 전송 됩니다. 그런 다음 요청 내용에 대한 Mysql 프로토콜 패킷을
구문 분석 합니다. 그다음. Syntax parsing 수행한다. 쿼리 플랜 최적화를 만든다 그리고 계획을 실행하여 데이터에 엑세스하고 처리 합니다.
모든 데이터는 TiKV Cluster안에 저장 된다. TiDB-server는 프로세스 중에 데이터에 엑세스 하기 위해 TiKV-server와 상호 작용해야 한다.
마지막으로, TiDB-Server는 Query 결과를 사용자에게 반환 해야 합니다.


[Summary]
지금까지는 SQL의 관점에서 데이터를 저장하고 조작에 사용하는 방법을 알았습니다. 최적화 원칙 및 분산 실행 프레임 워크의 세부 사항과 같은 SQL 계
층에 대한 정보가 앞으로 소개 될 것입니다. 다음 기사에서는 PD에 대한 정보, 특히 클러스터 관리 및 일정에 대해 설명합니다. 이것은 TiDB를 사용할 
때 보이지 않지만 전체 클러스터에 중요한 것을 볼 수 있기 때문에 흥미로운 부분입니다.

3. Scheduling

[why scheduling]
내부 TiDB 첫번째 블로그에서, 우리는 TiKV 클러스터가 TiDB 데이터베이스의 분산 KV 스토리지 엔진이라는 것을 알고 있습니다.
데이터는 복제된다 그리고 Reginon으로 관리된다 그리고 각각의 Region에서는 다른 TikV node에 부산 된 여러 개의 복제본이 있
습니다. 이 복제품들 사이에서, 리더는 읽기/쓰기를 담당하고 추행자는 리더의 Raft 로그를 보내 동기화 시킨다.
지금, 다음의 질문에 대하여 생각해 보십시오.


* 같은 Region의 여러 복제본이 다른 노드에 배포 되도록 하는 방법은 무엇입니까?
  하나의 머신에서 여러 TiKV 인스턴스를 시작하면 어떻게 됩니까?

* TiKV 클러스터가 재나 복구를 위해 다중 사이트 배포를 수행 할 때, Raft Group의 여러 복제본이 하나의 장애가
  발생하면 손실되지 않도록 보장하는 방법

* TiKV 클러스터에 있는 다른 노드의 데이터를 새로 추가된 노드로 이동하는 방법?

* 노드가 실패 하면 어떻게 됩니까? 전체 클러스터는 무엇을 해야 합니까? 
  만약 노드가 일시적으로 실패 했다면(ex: service restarting?) 
  오랫동안 실패한 것은 어떨까요?(e.g. disk failure 또는 data 손실)?

* 각 Raft Group에 n개의 복제본이 있어야 한다고 가정 합니다. 싱글 Raft Group은 복제본이 불충분 할 수 있다.
  (e.g node failure or 복제 손실) 번호를 예약 하는 방법은 ?

* 리더에 의해 읽기/쓰기가 수행 되므로, 모든 리더가 몇 개의 노드에 모일 경우 클러스터에 어떤 일이 발생 합니까?

* 모든 Region에 접근할 필요가 없다. 그리고 핫스팟은 아마 몇몇 지역에 있습니다. 이경우 우리는 무엇을 해야 합니까?

* 클러스터는 로드 밸런싱 중에 데이터 이관을 해주어야 한다. 이러한 종류의 데이터 마이그레이션은 실질적인 네트워크
  대역폭을 소비하게 될 것이며, disk io 및 cpu 와 온라인 서비스에 영향을 미치는가?


위의 질문을 하나씩 해결 하는 것은 쉽다, 그러나 한번 섞여진것은 어렵다. 하나의 Raft 집단의 내부 상황을 고려할 필요가
있는 질문이 몇가지가 있다. 예를 들면, 복제복을 추가 할지 여부는 해당 수가 충분하면 결정된다. 실제로 이 복제본을 추가할
전역 보기가 필요하다. 전체 시스템이 동적으로 변경 됩니다. 지역 분리와 같은 상황, 노드 조인, 노드 실패 그리고
변경 사항에 발생 하는 핫스팟은 끊임없이 발생한다. 일정 시스템은 또한 최상의 상태로 진행 되야 한다. 마스터가 할 수 없는
구성요소가 없으면, 스케쥴링 및 글러벌 정보 구성, 이러한 요소를 충족하기가 어렵다.
그래서, 우리는 제어 할 수 있는 중심 노드가 필요하다. 그리고 시스템의 전반적인 상황을 조절한다.
여기에서는 배치 드라이버(PD)모듈이 제공 된다.

woong : 시스템의 전반적인 상황을 조절한다.

[The Requirements of scheduling]
나는 이전 열거된 list 질문에 대해 분류 및 정렬 하고 싶다. 일반적으로, 두개의 타입이 있다.

* 분산 및 고가용성 스토리지 시스템은 다음 요구 사항을 충족 해야 합니다.
  * 올바른 수의 복제본
  * 복제본은 다른 머신으로 분산 되어야 한다.
  * 노드를 추가한 후 다른 노드의 복제본을 마이그레이션 할 수 있다.
  * 노드가 오프라인이면 이 노드의 데이터를 마이그레이션 해야 한다.

* 좋은 시스템은 다음과 같은 체적화가 필요하다.
  * 클러스터에 균형 잡힌 리더 분포.
  * 각 노드의 균형 있는 스토리지 용량.
  * 핫스팟 접속 시 균형 있는 분산.
  * 온라인 서비스에 영향을 주지 않기 위해 균형 조정의 속도를 제어 합니다.
  * 수동으로 온라인 / 오프라인 노드 및 자동으로 오프라인 오류 노드를 포함한 노드 상태 관리.

첫 번째 유형의 요구 사항이 충족되면 시스템은 다중 복제 재해 복구, 동적 확장 성, 노드 장애 허용 및 자동 재해 복구를 지원합니다. 
두 번째 유형의 요구 사항이 충족되면 시스템로드가 보다 균형 있고 관리하기 쉬워집니다. 이러한 요구를 충족시키기 위해서는 먼저 각 
노드의 상태, 각 Raft 그룹의 정보 및 비즈니스 액세스 및 운영 통계와 같은 충분한 정보를 수집해야합니다. 그런 다음이 정보와 일정 
정책에 따라 이전 요구 사항을 충족시킬 일정 계획을 수립하기 위해 PD에 대한 몇 가지 정책을 설정해야합니다.


[The Basic Operations of Scheduling]
기본 동장은 가장 간단하다. 다른 말로, 스케쥴 정책을 충족시키기 위해 할수 있는 일. 이 것은 전체 스케쥴러의 핵심이다.
이 이전의 스케쥴러 요구사항은 복잡해 보인다. 그러나 3개의 조작으로 일반화 할 수 있다.

- Add a Replica.
- Delete a Replica.
- Raft Group의 다른 복제본들 사이에 리더의 역할을 전이 시킨다.

Raft 포로토콜은 이러한 요구 사항을 충족 시킨다: 
AddReplica, RemoveReplica and TransferLeader 명령은 세가지 기본 조작을 지원한다.


[Information Collection]
스케쥴은 전체 클러스터의 정보 수집에 달려 있다. 간달히 말해서, 우리는 각 TiKV 및 각 Regioin 상태를 알아야 한다.
TiKV 클러스터는 두 종류의 정보를 PD에 보고 합니다.

* 각 TIKV 노드는 정기적으로 노드의 전반적인 정보를 PD에 보고 합니다. TiKV Store와 PD 사이에는 하트비트가 있습니다.
한편으로는, PD는 각 저장소가 활성 상태인지 또는 하트 비트를 통해 새로 추가 된 저장소가 있는지 여부를 확인합니다.
한편으로는, 하트비트는 스토어의 상태 정보를 나른다.

  * total disk 용량
  * free dsk 용량
  * region의 number
  * 데이터 기록 속도
  * 송수신된 스냅샵의 수
  * 과부하인지 여부
  * 라벨 정보 (레이블은 게층 적 관계가 있는 일련의 태그 입니다)

* 각 Raft Group의 리더는 정기적으로 각 Raft 그룹의 리더에게 PD에게 보고하고 PD는 연결된 하트비트와 연결 됩니다.
  * Reader의 위치
  * 추종자의 위치
  * 오프라인 복제본 수
  * 데이터 읽기/쓰기 속도

이 두 종류의 하트 비트를 통해 PD는 전체 클러스터 정보를 수집 한 다음 의사 결정을 내립니다. 또한 PD는 관리 인터페이
스를 통해 추가 정보를 얻음으로써 보다 정확한 의사 결정을 내릴 수 있습니다. 
예를 들어, 상점의 하트 비트가 중단되면 PD는 일시적인지 또는 영구적인지 여부를 알 수 없습니다. PD는 일정 시간 동안 만 
기다릴 수 있습니다 (기본적으로 30 분). 아직 하트 비트가 없으면 PD는 상점이 오프라인이고 상점의 모든 region을 멀리 
옮겨야한다고 간주 합니다. 그러나 운영 직원이 기계를 수동으로 오프라인으로 전환하면 관리 인터페이스를 통해 매장을 
사용할 수 없음을 PD에 알려야 합니다. 이 경우 PD는 즉시 저장소의 모든 영역을 멀리 이동시킵니다.

[The Policy of Scheduling]
정보를 수집 한 후, PD는 구체적인 일정 계획을 작성하는 몇 가지 정책을 필요로합니다.

1. 한 Region 에 있는 복제본의 수는 정확해야 합니다.
PD가 Region의 복제본 수가 Region Leader의 핵심 요소를 통해 요구 사항을 충족시키지 못하면 Add / Remove Replica 작업을 
통해 수를 수정합니다. 다음과 같은 경우에 발생할 수 있습니다.
  * 노드가 손실되어 모든 데이터가 손실되어 일부 지역에서는 복제본이 부족합니다.
  * 삭제된 노드는 다시 기능하고 자동으로 클러스터에 참여합니다. 이 경우 중복 복제본이있어 제거해야합니다.
  * 관리자는 복제본 정책과 max-replicas의 구성을 수정했습니다.

2. Raft Group의 여러 복제본은 같은 위치에 있으면 안됩니다.
동일한 노드가 아니라 동일한 노드임을주의하십시오. 일반적으로 PD는 여러 노드가 실패 할 때 많은 복제본이 손실되는 문제를 
피하기 위해 여러 노드가 동일한 노드에 있지 않을 것을 보장 할 수 있습니다. 실제 배포 시나리오에서는 다음 요구 사항이 발
생할 수 있습니다.
  * 여러 노드가 동일한 실제 시스템에 배치 되었다.
  * TiKV 노드는 여러 서버에 분배합니다. 서버의 전원이 꺼지더라도 시스템을 계속 사용할 수 있습니다.
  * TiKV 노드는 여러 IDC에 배포됩니다. 데이터 센터의 전원이 꺼지면 시스템을 계속 사용할 수 있습니다.

본질적으로, 당신이 필요로하는 것은 일반적인 위치 속성을 가지며 최소한의 결함 허용 단위를 구성하는 노드입니다. 이 유닛 
내부에는 여러 지역의 복제본이 공존하지 않기를 바랍니다. 이 때 PD의 노드 및 위치 레이블에 레이블을 구성하여 어떤 레이블을 
위치 식별자로 지정할 수 있습니다. 복제본을 배포 할 때 영역의 여러 복제본을 저장하는 노드는 동일한 위치 식별자를 갖지 
않습니다.

3. 저장소 전체에 복제본이 균등하게 분산됩니다. 각 복제본의 데이터 저장 용량이 고정되어 있으므로 각 노드의 복제본 수의 
균형을 유지하면 전체로드가 균형을 이루게됩니다.


4. 리더의 수는 상점간에 균등하게 분배됩니다.
Raft 프로토콜은 리더를 통해 읽고 씁니다. 따라서 계산로드는 주로 리더에 배치됩니다. 따라서 PD는 여러 저장소에 리더를 배포하는 
작업을 관리합니다.

5. 핫스팟의 수는 저장소간에 균등하게 분배 됩니다.
정보를 제출할 때 각 저장소 및 지역 리더는 키의 읽기 / 쓰기 속도와 같은 현재 액세스 로드 정보를 전달합니다. PD는 핫 스팟을 검사
하여 노드에 분산시킵니다.


6. 각 저장소의 저장 공간 점유율은 대략 동일하다.
각 저장소는 시작할 때 이 저장소의 저장소 공간 제한을 나타내는 Capacity 매개 변수를 지정합니다. PD는 스케줄링 할 때 노드의 
나머지 공간을 고려합니다.

7. 온라인 서비스에 영향을 미치지 않도록 일정 속도 제어
예약 작업은 CPU, 메모리, 디스크 I / O 및 네트워크 대역폭을 소비하므로 온라인 서비스에 영향을 미치지 않아야합니다. PD는 진행중인 작업의 수를 제어하며 기본 속도는 보수적입니다. 스케줄링 속도를 높이려면 (서비스 업그레이드를 중지하고, 새 노드를 추가하고, 가능한 한 빨리 스케줄을 잡으려는 등) pd-ctl을 통해 수동으로 가속화 할 수 있습니다.

8. 수동으로 오프라인 노드 지원
pd-ctl을 통해 수동으로 노드를 오프라인 상태로 만들 때 PD는 특정 속도 제어 내에서 노드의 데이터를 멀리 이동시킵니다. 그런 다음 노드를 
오프라인으로 설정합니다.

[The implementationof scheduling]

이제 일정 과정을 봅시다.

PD는 저장소 또는 리더의 하트 비트를 통해 지속적으로 정보를 수집하여 클러스터의 세부 데이터를 가져옵니다. 이 정보와 
일정 정책에 따라 PD는 운영 순서를 생성 한 다음 지역 리더가 보낸 하트 비트를 수신 할 때이 지역에서 수행 할 작업이 있
는지 확인합니다. PD는 하트 비트의 응답 메시지를 통해 다가오는 작업을 지역 리더에게 반환 한 후 다음 하트 비트에서 실행 
결과를 모니터링합니다. 이 작업은 지역 지도자 에게만 권장되는 것으로 실행이 보장되지는 않습니다. Region Leader는 현재 
상태에 따라 실행할 것인지 여부와 실행시기를 결정합니다.


[summary]
이블로그는 귀하가 다른 곳에서 찾을 수없는 정보를 공개합니다. 우리는 스케줄링을 위해 분산 스토리지 시스템을 구축하기 위해 
고려해야 할 사항과 정책의 유연한 확장을 지원하기 위해 정책과 구현을 분리하는 방법에 대해 더 잘 이해했기를 바랍니다.

우리는이 세 가지 블로그 (데이터 스토리지, 컴퓨팅 및 스케줄링)가 TiDB의 기본 개념과 구현 원칙을 이해하는 데 도움이되기를 
바랍니다. 앞으로 TiDB에 관한 더 많은 블로그가 코드에서 아키텍처로 이동합니다!

<< TiDB Quick Start Guide >>
[About TiDB]
TiDB는 오픈소스 분산 확장 하이브리드 트랜젝션 분석 프로세싱 데이터 베이스이다. 무한 수평 확장 성 및 강력한 일관성 및 고가용성을
제공 합니다. TiDB는 MySQL과 호환 됩니다. 그리고 OLTP  및 OLAP 작업을 한다.

[About this guide]
이 가이드는 TiDB-Ansible을 사용하여 TiDB 클러스터의 빠른 배포를 수행하는 방법을 설명하고 기본적인 TiDB 작업 및 관리 과정을 안내합니다.


[Deploy the TiDB cluster]
이장에서 TiDB Cluster를 배포하는 방법에 대해 설명 합니다. TiDB 클러스터는 서로 다른 구성 요소로 구성 됩니다.
TiDB servers, TiKV servers, and Placement Drive(PD) servers.

architecture는 다음과 같다.



[Try TiDB]
이장은 TidB의 기본적인 CRUD 조작에 대해 서술한다.

[Create,show,and drop a database]

* 데이터베이스를 만들려면 CREATE DATABASE 문장을 사용한다. 구문은 다음과 같다.
CREATE DATABASE db_name [options];

예를 들면, 다음의 명령문은 samp_db 이름으로 데이터베이스를 생성한다.
CREATE DATABASE IF NOT EXISTS samp_db;


* 데이터베이스를 보려면, SHOW DATABASE 명령문을 사용한다.
SHOW DATABASE;

* 데이터베이스를 지우려면, DROP DATBASE문을 사용한다. 예를 들면:
DROP DATABASE samp_db;

[Create,show,adn drop a table]
Table를 생성 하려면, CREATE TABLE 명령문을 사용한다. 구문은 다음과 같다.
CREATE TABLE TABLE_NAME COLUMN_NAME DATA_TYPE CONSTRAINT;

example)
CREATE TABLE person (
number INT(11),
name VARCHAR(255),
birthday DATE
);
 
테이블이 존재할 경우 오류룰 방지하기 위해 존재하지 않을 경우 추가:

CREATE TABLE IF NOT EXISTS person (
number INT(11),
name VARCHAR(255),
birthday DATE
);


* 테이블을 생성하는 명령문을 보려면, SHOW CREATE 명령문을 사용한다.
exampe) SHOW CREATE TABLE PERSON;

* 데이터베이스의 모든 테이블을 보려면, SHOW TABLES 명령문을 사용한다.
exampe) SHOW TABLES FROM SAMP_DB;

* 테이블의 모든 컬럼 정보를 보려면, SHOW FULL COLUMNS 명령문을 사용한다.
example) SHOW FULL COLUMNS FROM person;

* 테이블을 삭제 하려면, DROP TABLE 명령문을 사용한다.
example) DROP TABLE person; or DROP TABLE IF EXISTS person;

[CREATE, SHOW, AND DROP an Index]
not unique 값의 전체 열에 대한 index column을 만들려면, CREATE INDEX or ALTER TABLE 명령문을 사용한다.
example) CREATE INDEX person_num ON person(number); or ALTER TABLE person ADD INDEX person_num(n umber);

* unique value 컬럼에 대한 unique index를 생성한다. CREATE UNIQUE INDEX or ALTER TABLE 명령문을 사용한다. 
exampl) CREATE UNIQUE INDEX Person_num on person(number); or ALTER TABLE person ADD unique person_num on (number);

* 테이블의 모든 Index 보여준다. SHOW INDEX 명령문을 사용한다.
SHOW INDEX from person;

* 인덱스를 삭제한다. DORP INDEX or ALTER TABLE 명령문을 사용한다.
example) DROP INDEX person_sum ON person; ALTER TABLE person DROP INDEX person_num;

[Insert, Select, Update, and delete data]
* table에 Insert한다, INSET 문을 사용한다.
example)InSERT INTO person VALUES("1", "tom","20170912");

* Table의 데이터를 보여준다, select 문을 사용한다.
example) SELECT * FROM person;
+--------+------+------------+
| number | name | birthday |
+--------+------+------------+
| 1 | tom | 2017-09-12 |
+--------+------+------------+


* 테이블에 UPDATE 하려면, UPDATE 문장을 사용한다.
UPDATE person SET birthday='20171010' WHERE name='tom';
SELECT * FROM person;

* 테이블에 delete 하려면, DELETE 문장을 사용한다.
DELETE FROM person WHERE number=1;
SELECT * FROM person;

[CREATE, authorize, and delete a user]
* USER를 생성 하려면, CREATE USER 명령문을 사용한다. 다음의 예제는 user 이름 tiuser password 123456으로 생성한다.
CREATE USER 'tiuser'@'localhost' IDENTIFIED BY '123456';

* tiuser에게 samp_db database 테이블을 검색할 수 있는 권한을 부여 한다.
GRANT SELECT ON samp_db.* TO 'tiuser'@'localhost';

* tiuser의 권한을 체크한다.
SHOW GRANTS for tiuser@localhost;

* tiuser 삭제한다.
DROP USER 'tiuser'@'localhost';


[Monitor the TiDB Cluster]
부라우저를 열어 모니터링 플랫폼에 접속 하십시오: http://172.16.10.3:3000.
default 접속 passwrord는 admin/amdin

[About Key metrics]
Service
Panel Name
Description
Normal Range
PD
Storage Capacity
the total storage capacity of the TiDB cluster
PD
Current Storage Size
the occupied storage capacity of the TiDB cluster
TiDB Cluster 점유된 스토리지 용량
PD
Store Status – up store
the number of TiKV nodes that are up
올라간 TiKV node 수
PD
Store Status – down store
the number of TiKV nodes that are down
내려간 TiKv Node 수
0. If the number is bigger than 0, it means some node(s) are not down.
숫자가 0보다 큰경우
그곳은 다운되지 않았
다는 의미이다.
PD
Store Status – offline store
the number of TiKV nodes that are manually offline
수동으로 오프라인된 TiKV 노드의 수
PD
Store Status – Tombstone store
the number of TiKV nodes that are Tombstone
삭제 표시가 있는 TiKV 노드의 수
PD
Current storage usage
the storage occupancy rate of the TiKV cluster
TiKV cluster의 스토리지 점유율
If it exceeds 80%, you need to consider adding more TiKV nodes.
점유율이 80% 넘는다면 노두 추가가 필요하다.
PD
99% completed cmds duration seconds
99% 완료된 지속 시간(초)
the 99th percentile duration to complete a pd-server request
pd-server 요청을 완료 하기 위한 99% 기간
less than 5ms
5분 미만
PD
average completed cmds duration seconds
명령의 평균 완료 지속 시간(초)
the average duration to complete a pd-server request
PD 서버 요청의 평균 지속 시간
less than 50ms
5분 미만
PD
leader balance ratio
the leader ratio difference of the nodes with the biggest leader ratio and the smallest leader ratio
리더 비율이 가장 큰 것과 리더 비율이 가장 작은 것과 리더 비율의 차이
It is less than 5% for a balanced situation. It becomes bigger when a node is restarting.
균형 잡힌 상태에서 5%미만 이어야 한다.  노드가 다시 시작 할 때 커진다.
PD
region balance ratio
region 밸런스 비율
the region ratio difference of the nodes with the biggest region ratio and the smallest region ratio
노드의 큰 region 비율과 작은 region 비율에서 region 비율의 차이
It is less than 5% for a balanced situation. It becomes bigger when adding or removing a node.
균형 상태는 5% 미만이어야 한다. 크다면 Node를 추가 하거나 삭제 해야 한다.
TiDB
handle requests duration seconds
요청 지속 시간(초)
the response time to get TSO from PD
PD에서 TSO을 얻는 응답 시간
less than 100ms
100ms 미만
TiDB
tidb server QPS
the QPS of the cluster
application specific
특정 어플리케이션
TiDB
connection count
the number of connections from application servers to the database
응용 프로그램 서버에서 데이터베이스의 연결 수
Application specific. If the number of connections hops, you need to find out the reasons. If it drops to 0, you can check if the network is broken; if it surges, you need to check the application.
특정 어플리케이션. 접속 HOPS 수,  너는 이유를 찾아야 한다. 
0으로 떨어지면, 너는 네트워크가 고장 났는지 체크 할 수 있다. 어플케이션 체크가 필요하다.
TiDB
statement count
the number of different types of statement within a given time
주어진 시간동안 수행 된 다양한 유형의 수.
application specific
특정 어플리케이션
TiDB
Query Duration 99th percentile
99% 쿼리
the 99th percentile query time
99% 쿼리 시간.
TiKV
99% & 99.99% scheduler command duration
99% 스케쥴 명령 기간
the 99th percentile and 99.99th percentile scheduler command duration
For 99%, it is less than 50ms; for 99.99%, it is less than 100ms.
99%, 5ms 이내, 99.99% 100ms 이내.
TiKV
95% & 99.99% storage async_request duration
95% & 99.99% 스토리지 aync_requect 지속.
the 95th percentile and 99.99th percentile Raft command duration
95th & 99.th % Rafrt 명령 기간
For 95%, it is less than 50ms; for 99.99%, it is less than 100ms.
95% 50ms 이내, 99.99% 100ms 이내
TiKV
server report failure message
There might be an issue with the network or the message might not come from this cluster.
네트워크의 이슈나 클러스의 지원하지 않는 메시지에서 나타날 수 있다.
If there are large amount of messages which contains unreachable, there might be an issue with the network. If the message contains store not match, the message does not come from this cluster.
연결수 없는 대량의 메세지가 있다면 네트워크 문제 이거나 Cluster에서 제공하지 않는 메세지이다.
TiKV
Vote
the frequency of the Raft vote
Raft vote 빈도
Usually, the value only changes when there is a split. If the value of Vote remains high for a long time, the system might have a severe issue and some nodes are not working.
보통, Split 할때 값만 변경 된다.  긴 시간동안 vote 나머지가 높게 유지 되었다면 시스템은 서버의 이슈가 있거나 일부 노드가 작동 하지 않고 있다.
TiKV
95% and 99% coprocessor request duration
the 95th percentile and the 99th percentile coprocessor request duration
Application specific. Usually, the value does not remain high.
TiKV
Pending task
the number of pending tasks
Except for PD worker, it is not normal if the value is too high.
TiKV
stall
RocksDB stall time
If the value is bigger than 0, it means that RocksDB is too busy, and you need to pay attention to IO and CPU usage.
TiKV
channel full
The channel is full and the threads are too busy.
If the value is bigger than 0, the threads are too busy.
TiKV
95% send message duration seconds
the 95th percentile message sending time
less than 50ms
TiKV
leader/region
the number of leader/region per TiKV server
application specific




<< TiDB Tutorial >>
TiDB는 PingCAP에 의해 구축 된 오픈 소스 분산 형 하이브리드 처리 및 분석 처리 (HTAP) 데이터베이스로 동일한 데이터웨어 
하우스에있는 실시간 트랜잭션 데이터에 대해 실시간 데이터 분석을 수행 할 수있게 해줍니다. ETL, T + 1, 더 많은 지연. 
200 개 이상의 회사가 현재 TiDB를 생산에 사용하고 있습니다. 2.0 버전은 2018 년 4 월 말에 출시되었습니다.

이 5 분짜리 튜토리얼에서는 로컬 컴퓨터에서 Docker Compose를 사용하여 표준 TiDB 클러스터를 스핀 업하는 방법을 보여주기 
때문에 업무용 또는 자체 프로덕션 환경에서 사용하기 전에 하이브리드 전원을 맛볼 수 있습니다. 표준 TiDB 클러스터에는 
TiDB (MySQL 호환 무 상태 SQL 계층), TiKV (데이터가 저장되는 분산 트랜잭션 키 값 저장소) 및 TiSpark (TiDB 생태계 내에서 
복잡한 분석 쿼리를 지원하는 Apache Spark 플러그인)가 포함됩니다.

NOTE : 위의 가이드는 Max 사용자를 위한 가이드이다.

[setting up]
우리가 TiDB를 배포하기 전에 몇가지 작업이 필요하다: brew,wget,Git,Docker,Mysql Client.
니가 이미 가지고 있지 않다면, 여기에 그것을 얻기 위한 지시 사항이 있다.

1. To Install brew, go here
2. to install wget, 너의 터미널에서 다음 아래의 명령을 사용 한다.
   brew install wget --with-libressl
3. Git 설치, 너의 터미널에서 아래의 명령을 수행 한다.
   
brew install git

4. docker 설치,  Install Docker: https://www.docker.com/community-edition.

5. mysql client install
brew install mysql-client

[Spin up a TiDB cluster]
Docker 설치 되었다면 TiDB 지금 배포 하자.

1. Clone TiDB Docker를 너의 데스크탑에 구성한다.


2. 선택적으로, 너는 최신 Docker images 가지고 docker-compose pull로 사용 할 수 있다.
docker-compose pull

3. tidc-docker-compose 디렉토리로 변경 한다.
cd tidb-docker-compose

4. 데스크탑에 TiDB를 배포한다.
docker-compose up -d


너는 TiDB Cluster를 Default로 구성 하였다면 터미널 시작 시 메세지를 볼 수 있다.  1 TiDB instance, 3 TiKV instances,
3 Placement Driver (PD) instances, Prometheus, Grafana, 2 TiSpark instances(one master, one slave), and a TiDB-Vision instance.

터미널에서 다음과 같은 내용이 보일 것이다.


축하한다~ 너의 랩탑에 TiDB Cluster를 배포 하였다.

배포가 성공 적인지 체크하는 방법은 다음과 같다:

* 다음 : Grafana 시작은 http://localhost:3000 default user/password:admin/amin.
  * 홈으로 이동하여 풀다운 메뉴를 클릭하면 다양한 TiDB 구성 요소의 대시 보드를 볼 수 있습니다 :  TiDB, TiKV, PD, entire cluster.
  * 너는 현재 TiDB cluster의 상태를 패털 데시보드로 볼 수 있을 것이다.



* TiDB-version at http://localhost:8010 가라.
  (TiDB-vision은 Cluster 내부의  Data 이동 및 로드 밸렁싱 정보를 비쥴얼 Tool로 보여준다.)
  * 너는 3개의 TiKV node의 링을 볼 수 있다. TiKV는 일관성 및 높은 지속성을 Raft 일치 Protocol로 적용 하였다. 
    밝은 그레이 블록은 빈공간이다, 짙은 그레이 블록은 Raft 추종자이다. 그리고 짙은 그린 블럭은 Raft 지도자 이다.
    너는 녹색 그린이 깜빡임은 TiKV 노드의 통신을 나타낸다.

  * 다음과 같이 보인다.





[Mysql TiDB 호환성 테스트]
우리가 언근했던 것처럼, TiDB는 MySQL 호환된다. 즉각적인 수평 확장 성을 갖춘 TiDB를 MySQL 슬레이브로 사용할 수 있습니다.



Mysql 호환성을 테스트 준비 :
1. tidb0docker-compose 수행 해야 한다, 그리고 새로운 터미널 Tab을 오픈 한다.
2. path를 Mysql 추가 한다.
   export PATH=${PATH}:/usr/local/mysql/bin
3. Mysql Cliet로 TiDB에 접속한다.
   mysql -h 127.0.0.1 -P 4000 -u root
   Result : 다음의 메세지를 볼 수 있을 것이다. TiDB는 MySQL Instance에 실제로 연결 된다.

   Server version: 5.7.10-TiDB-v2.0.0-rc.4-31
   



[Data를 가져오자]
약간의 sample data 가지고 와 수행을 해볼 수 있을 것이다.

1. 새로운 탭 또는 창을 열고  tispark-sample-data.tar.gz file을 다운 받아라.

2. 압축을 풀어라.
tar zxvf tispark-sample-data.tar.gz

3. Mysql의 sample data 폴더에 있는 sampel test data를 주입한다.
mysql --local-infile=1 -u root -h 127.0.0.1 -P 4000 < dss.ddl

4. Mysql 클라이언트 윈도우 또는 탭으로 돌아가서 거기에 있는 내용을 확인 하시오.
show databases;

list에서 TPCH-001 데이터베이스를 볼 수 있다. 그것은 우리가 방금 포팅한 샘플 데이터이다.
mysql> show databases;
+--------------------+
| Database           |
+--------------------+
| INFORMATION_SCHEMA |
| PERFORMANCE_SCHEMA |
| TPCH_001           |
| mysql              |
| test               |
+--------------------+

TPCH_001로 접속:
USE TPCH_001;
SHOW TABLES;

Result : TPCH_001의 모든 테이블을 볼 수 있다, like NATION, ORDERS, etc.

5. NATION Table에 있는 것을 봐라:
select * from nation;

결과 : 몇 가지 키와 설명이 있는 국가 목록이 표시 됩니다.




[TiSpark 수행]

이제 파이브리드 데이터베이스 퍼즐의 마지막 누락 부분인 Tispark를 사직하자.

1. TiSpakr 같은 데이터를 다운로드한 같은 윈도우 창에서 tidb-docker-compose 디렉토리로 돌아가라.
2. 다음 명령어를 사용하여 TiDB의 Spark를 수행 하라.
   docker-compose exec tispark-master  /opt/spark-2.1.1-bin-hadoop2.7/bin/spark-shell
   몇분 걸릴것이다. 지금 Spark 시작해라~~~~



3. 다음 3개 명령어를 사용 한다. 
스파크 인스터스에 TiSpark 바인드 하는 것과 그리고 데이터베이스 TCH_001 매칭, 우리 Mysql있는 같은 Sample데이터를 이용 할 수 있다.

import org.apache.spark.sql.TiContext
val ti = new TiContext(spark)
ti.tidbMapDatabase("TPCH_001")

다음과 같이 보인다.


4. NAtion table를 보라.
spark.sql("select * from nation").show(30);



[하이브리드를 시작하자]
Mysql Table이나 창으로 돌아가자. 테이블을 변경한다. 그리고 변화가 tispark에 나타는지 확인 하십시오.

1.  In the MySQL client, try this UPDATE:
UPDATE NATION SET N_NATIONKEY=444 WHERE N_NAME="CANADA";

2. update가 제대로 되었는지 확인 하십시오.
SELECT * FROM NATION;

3. TiSpark 터미널로 가서 업데이터 되었는지 확인해 봐라.
spark.sql("select * from nation").show(30);


Mysql 과 TiSpark 같은 데이터이다. 새로운 분석 데이터를 바로 사용 할 수 있다. 

로컬 컴퓨터에 TiDB를 간단하게 배포하면 이제는 작동중인 하이브리드 처리 및 분석 처리 (HTAP) 데이터베이스가 있습니다. MySQL 클라이언트의 
데이터를 계속 변경 (트랜잭션 워크로드 시뮬레이션)하고 TiSpark (실시간 분석 시뮬레이션)의 변경 사항으로 데이터를 분석 할 수 있습니다.

<< TIDB 참고 문서 >>


<< TiDB User Guide :: TiDB Server Administration >>
1. The TiDB Server
[The TiDB Server]
TiDB는 TiDB 데이터베이스 관리 시스템을 가리킨다. 이 문서는 TiDB 클러스트의 기본적인 관리 기능을 설명한다.

[TiDB Cluster start configuration]
명령줄 또는 구성 파일을 이용하여 서비스 파라메터를 설정 할 수 있다. 명령행 매개 변수의 우선순위가 구성 파일 보다 높다.
같은 매개 변수가 양쪽으로 설정 되어 있다면, TiDB는 커멘드 라인의 매개 변수를 사용하여  설정된 값을 사용한다.

[TiDB system variable]
TiDB는 Mysql 시스템 변수와 호환 됩니다. 그리고 데이터베이스 동작을 조정하기 위해 고유한 시스템 변수를 정의 한다.

[TiDB System Table]
Mysql 비슷하게, TiDB 또한 TiDB 수행 시 필요한 정보를 저장하는 시스템 테이블을 가지고 있다.

[TiDB data directory]
TiDB 데이터는 스토리지 엔진에 저장된다 그리고 데이터 디렉토리는 사용된 스토리지 엔진의 따라 다르다. 
로컬 저장 엔진을 사용할 때, 데이터는 로컬 하드디스크에 저장된다 그리고 디렉토리 위치는 path 파라메터로 제어 된다.

TiKV 저장 엔진을 사용할 때, 데이터는 TiKV Node에 저장된다 그리고 디렉토리 위치는 data-dir 파라메터로 제어 한다.

[TiDB server logs]
TiDB cluster(tidb-server,tikv-server and pd-server) 세개의 구성요소는 기본적인 표준 에러 로그를 출력 한다. 
세개의 구성요소 각각에서, --log-file 파라메터로 설정 할 수 있다. (또는 구성파일의 구성 항목) 그리고 파일안에
로그를 출력한다.
구성 파일을 사용 하여 로그 작동을 조절 할 수 있다. 

2. The TiDB Command Options
문서는 TiDB 서버 구성 파일 및 Startup 옵션을 설명 한다.

[TiDB Startup Options]
TiDB 프로세서를 시작 할 때 몇가지 프로그램 옵션을 지정할 수 있다.
TiDB 많은 옵션을 지원 한다. 다음 명령어를 수행 하여 간략한 정보를 먿는다.
./tidb-server --help












'sunjesoft > Goldilocks Extern DB' 카테고리의 다른 글

windows oracle 설치  (0) 2019.01.30
8a(china cluster db)  (0) 2019.01.30