다운 타임 제로 구축-전환 Db 스키마


14

다운 타임 제로 구축 달성 에도 동일한 문제가 있었지만 고려중인 전략에 대한 조언이 필요합니다.

문맥

서버 측 처리를위한 Apache / PHP 및 지속성을위한 MySQL DB / 파일 시스템을 갖춘 웹 기반 애플리케이션.

우리는 현재 인프라를 구축하고 있습니다. 모든 네트워킹 하드웨어에는 중복성이 있으며 모든 기본 네트워크 케이블은 내결함성을 위해 본드 쌍으로 사용됩니다. 서버는 하드웨어 내결함성을 위해 고 가용성 쌍으로 구성되며 가상 시스템 내결함성과 일반 성능 모두에 대해로드 밸런싱됩니다.

다운 타임없이 애플리케이션에 업데이트를 적용 할 수있는 것이 나의 의도입니다. 인프라를 설계 할 때 100 % 가동 시간을 제공 할 수 있도록 큰 어려움을 겪었습니다. 업데이트가 적용될 때마다 10-15 분의 다운 타임을 갖는 것은 매우 실망 스러울 것입니다. 릴리스주기가 매우 빠를 때 특히 중요합니다 (때로는 하루에 하나 이상의 릴리스에 도달 할 수 있음).

네트워크 토폴로지

이것은 네트워크의 요약입니다 :

                      Load Balancer
             |----------------------------|
              /       /         \       \  
             /       /           \       \ 
 | Web Server |  DB Server | Web Server |  DB Server |
 |-------------------------|-------------------------|
 |   Host-1   |   Host-2   |   Host-1   |   Host-2   |
 |-------------------------|-------------------------|
            Node A        \ /        Node B
              |            /            |
              |           / \           |
   |---------------------|   |---------------------|
           Switch 1                  Switch 2

   And onward to VRRP enabled routers and the internet

참고 : DB 서버는 마스터-마스터 복제를 사용합니다

제안 된 전략

이를 위해 현재 DB 스키마 업그레이드 스크립트를 두 부분으로 나눌 생각입니다. 업그레이드는 다음과 같습니다.

  1. 노드 A의 웹 서버는 오프라인 상태입니다. 노드 B의 웹 서버에서 트래픽을 계속 처리합니다.
  2. 전환 스키마 변경 사항이 DB 서버에 적용됩니다.
  3. 웹 서버 코드베이스가 업데이트되고 캐시가 지워지며 다른 업그레이드 작업이 수행됩니다.
  4. 웹 서버 A가 온라인 상태가되고 웹 서버 B가 오프라인 상태가됩니다.
  5. 웹 서버 B 코드베이스가 업데이트되고 캐시가 지워지며 다른 업그레이드 작업이 수행됩니다.
  6. 웹 서버 B가 온라인 상태가됩니다.
  7. 최종 스키마 변경 사항이 DB에 적용됩니다

'Transitional Schema'는 버전 간 호환 가능한 DB를 구축하도록 설계되었습니다. 이것은 대부분 이전 버전 스키마를 시뮬레이션하는 테이블 뷰를 사용하는 반면 테이블 자체는 새로운 스키마로 변경됩니다. 이를 통해 이전 버전이 정상적으로 DB와 상호 작용할 수 있습니다. 테이블 이름에는 어떤 테이블에 쓸지 혼동하지 않도록 스키마 버전 번호가 포함됩니다.

'최종 스키마'는 이전 버전과의 호환성을 제거하고 스키마를 정리합니다.

질문

요컨대, 이것이 효과가 있습니까?

더 구체적으로:

  1. 전환 스키마 변경의 특정 시점에서 동시 쓰기 가능성으로 인해 문제가 발생합니까? 테이블을 수정하고 이전 버전과 호환되는보기를 만드는 쿼리 그룹이 연속적으로 실행되도록하는 방법이 있습니까? 즉, 스키마 변경이 완료 될 때까지 다른 쿼리가 버퍼에 유지됩니다. 일반적으로 밀리 초입니다.

  2. 다운 타임없이 업데이트를 허용하면서 이러한 정도의 안정성을 제공하는 더 간단한 방법이 있습니까? 이전 버전과의 스키마 호환성에 얽매이지 않기 위해 '진화적인'스키마 전략을 피하는 것이 좋습니다.

답변:


4

실제로 찾고있는 것이 Continuous Availability 가 필요한만큼 고 가용성이 아닌 것 같습니다 .

기본적으로 계획은 작동하지만 설정의 주요 결함은 릴리스의 데이터베이스 스키마 변경으로 인해 다운 타임 또는 여전히 사용 가능한 노드가 올바르게 작동하지 않을 수 있다는 점에 주목 한 것 같습니다. Continuous Availability 접근 방식은 기본적으로 여러 프로덕션 환경을 만들어이를 해결합니다.

생산 하나

이 환경은 사용자가 현재 사용중인 소프트웨어의 현재 라이브 버전입니다. 자체 웹 서버, 애플리케이션 서버 및 데이터베이스 서버 및 테이블 스페이스가 있습니다. 다른 환경과 독립적으로 작동합니다. 이러한 서비스에 대한 도메인 분석 엔드 포인트를 소유 한 Load Balancer는 현재 이러한 웹 서버를 가리키고 있습니다.

생산 2

이것은 기본적으로 Production One과 동일한 릴리스 준비 환경입니다. 여기에서 릴리스 업그레이드를 수행하고 실시간 이벤트 전에 위생 테스트를 수행 할 수 있습니다. 또한이 환경에서 데이터베이스 변경을 안전하게 수행 할 수 있습니다. 로드 밸런서는 현재이 환경을 가리 키지 않습니다.

생산 DR

이것은 세계의 다른 지역에있는 별도의 데이터 센터에있는 또 하나의 복제본입니다. 이를 통해로드 밸런서에서 DNS 스위치를 수행하여 치명적인 이벤트 발생시 페일 오버 할 수 있습니다.

생중계

이 이벤트는 기본적으로 프로덕션 1에서 프로덕션 2로 또는 그 반대로 프로덕션 2로 순환하도록 DNS 레코드를 업데이트합니다. 전 세계의 DNS 서버 전체에 전파되는 데 시간이 걸리므로 두 환경을 잠시 동안 실행 상태로 두십시오. 일부 사용자는 이전 버전의 소프트웨어에서 기존 세션에서 작업 할 수 있습니다. 대부분의 사용자는 업그레이드 된 버전의 소프트웨어에서 새 세션을 설정합니다.

데이터 이동

여기서 유일한 단점은 해당 기간 동안 모든 사용자가 해당 기간 동안 모든 데이터를 사용할 수 없다는 것입니다. 이전 버전 데이터베이스에는 새로운 데이터베이스 스키마로 안전하게 마이그레이션해야하는 중요한 사용자 데이터가 있습니다. 이는 잘 테스트 된 데이터 내보내기 및 마이그레이션 스크립트 또는 배치 작업 또는 유사한 ETL 프로세스로 수행 할 수 있습니다.

결론

릴리스 이벤트를 완전히 완료하면 이제 프로덕션 2가 기본이되고 다음 배포주기 동안 프로덕션 릴리스에 다음 릴리스를 설치하기 시작합니다.

단점

이는 복잡한 환경 설정이며 많은 양의 시스템 리소스가 필요하며, 시스템 리소스를 성공적으로 수행하려면 2 ~ 3 배가 소요됩니다. 이 방법을 사용하면 특히 사용량이 많은 대용량 시스템을 사용하는 경우 비용이 많이들 수 있습니다.


따라서 내가 올바르게 이해했다면 Db를 계속 사용하는 동안 적용되는 '전환'DB 스키마 변경 대신 Db-A가 기존 스키마와 온라인으로 유지되고 Db-B가 새로운 스키마로 업데이트되는 것이 좋습니다 개요. 업데이트를 릴리스 할 준비가되면 웹 서버가 변경되고 업데이트가 준비되는 동안 Db A에 기록 된 데이터가 Db B로 마이그레이션됩니다 (아마도 특정 타임 스탬프 후에 모든 변경 사항이 적용됨).
Marvin

@PeterScott 당신은 그것을 얻었다. 모든 활성 세션이 이전 시스템에서 끝나고 모든 DNS 캐시가 새 CNAME 또는 IP 주소로 업데이트 될 때까지 시간이 오래 걸리기 전에는 스크립트를 실행하고 싶지 않습니다.
maple_shaft

1
나는 두 가지 측면 모두에서 괜찮을 것입니다. 세션이 특정 가상 시스템에 연결되지 않도록 서버 저장소가 아닌 Db에서 세션이 유지되고 있으며 현재 비 DNS 기반 부하 분산 장치를 사용하려고합니다. 데이터 센터 수준의 중복성은 없지만 애플리케이션 시작 후 1 년 정도 기다릴 수 있습니다.
Marvin

2

당신의 전략은 건전합니다. 나는 "전환 스키마"를 완전한 "트랜잭션 테이블"세트로 확장하는 것을 고려할 것입니다.

트랜잭션 테이블을 사용하면 정확성을 보장하기 위해 정규화 된 테이블에 대해 SELECT (쿼리)가 수행됩니다. 그러나 모든 데이터베이스 INSERT, UPDATE 및 DELETE는 항상 비정규 화 된 트랜잭션 테이블에 기록됩니다.

그런 다음 별도의 동시 프로세스가 해당 변경 사항 (아마도 스토어드 프로 시저 사용)을 설정된 비즈니스 규칙 및 스키마 요구 사항에 따라 정규화 된 테이블에 적용합니다.

대부분의 경우 이것은 거의 즉각적입니다. 그러나 조치를 분리하면 시스템이 과도한 활동 및 스키마 업데이트 지연을 수용 할 수 있습니다.

데이터베이스 (B)에서 스키마를 변경하는 동안 활성 데이터베이스 (A)의 데이터 업데이트는 해당 트랜잭션 테이블로 이동하여 즉시 정규화 된 테이블에 적용됩니다.

데이터베이스 (B)를 백업 할 때 (A)의 트랜잭션은 (B)의 트랜잭션 테이블에 기록하여 적용됩니다. 해당 부분이 완료되면 (A)가 중단되고 스키마 변경 사항이 적용됩니다. (B)는 (A)의 거래 적용을 마치는 동시에 (A)처럼 대기열에있는 라이브 거래를 처리하고 (A)가 돌아 왔을 때 "실제 거래"도 같은 방식으로 적용됩니다.

트랜잭션 테이블 행은 다음과 같습니다.

| ROWID | TRANSNR | DB | TABLE | SQL STATEMENT
    0        0       A    Name   INSERT INTO Name ...
    1        0       A    Addr   INSERT INTO Addr ...
    2        0       A    Phone  INSERT INTO Phone ...
    3        1       A    Stats   UPDATE Stats SET NrOfUsers=...

트랜잭션 "테이블"은 실제로 성능 요구 사항에 따라 별도의 NoSQL 데이터베이스 또는 심지어 순차 파일의 행일 수 있습니다. 보너스는 응용 프로그램 (이 경우 웹 사이트) 코딩이 트랜잭션 테이블에만 쓰기 때문에 조금 더 단순하다는 것입니다.

이 아이디어는 이중 입장 부기와 동일한 원칙을 따르며 유사한 이유로도 마찬가지입니다.

트랜잭션 테이블은 부기 "저널"과 유사합니다. 완전히 정규화 된 테이블은 부기 "선장"과 유사하며 각 테이블은 부기 "계정"과 다소 비슷합니다.

부기에서 각 트랜잭션은 분개에 두 개의 항목을 가져옵니다. 하나는 "직불 카드"원장 계정이고 다른 하나는 "신용"계정입니다.

RDBMS에서 "저널"(트랜잭션 테이블)은 해당 트랜잭션에 의해 변경 될 각 정규화 된 테이블에 대한 항목을 가져옵니다.

위의 표 그림에서 DB 열은 트랜잭션이 시작된 데이터베이스를 나타내므로 다른 데이터베이스의 큐에 대기 된 행을 필터링하여 두 번째 데이터베이스를 다시 가져올 때 다시 적용 할 수 없습니다.


1
나는 책 보관과 비교를 좋아한다. 그래서 이해했다면 트랜잭션 테이블을 사용하면 데이터를 특정 정규화 테이블에 쓰는 데 약간의 지연을 두어 변경 중반에 중단의 위험없이 모든 스키마 변경 사항을 적용 할 수 있습니까? 그런 다음 테이블의 스키마를 최신 상태로 유지하여 비정규 화 된 트랜잭션을 정규화 된 테이블에 적용하는 프로세스를 다시 시작할 수 있습니까 (이 프로세스는 기존 스키마 데이터 쿼리를 새 스키마에 매핑 할 수 있음)?
Marvin

1
예. 이전 데이터와 새 데이터를 모두 수용 할 수 있도록 매핑 저장 프로 시저 (또는 기타)를 수정합니다. 새 NOT-NULL 열은 "사용자 업데이트시이를 프롬프트합니다"라는 코드로 이전 데이터에서 채워질 수 있습니다. 분할 할 열 (예 : FULLNAME을 FIRST 및 LAST로)에는 일부 알고리즘이 필요합니다. 새로운 비즈 요구 사항을 위해 표에 하나 이상의 "설명과 같은"열을 추가하는 것이 좋습니다. 당신이하지 않으면, 나는 사용자가 그 목적을 위해 다른 열을 적절하게 보장하고 데이터를 수정하는 것이 거의 불가능하다는 것을 보증합니다.
DocSalvager

이전 스키마에 대해 구조화 된 SELECT 쿼리가 새 스키마에 적용되는 것을 어떻게 방지 할 수 있습니까? 테이블 뷰를 만들고 스키마 버전 번호를 사용하여 스키마 테이블의 이름을 바꿀 수는 있지만 스키마 변경 사항이 정규화 된 테이블에 직접 적용되므로 적용되는 동안 여전히 문제가 될 수 있습니다.
Marvin

1
RDBMS에 테이블, 열 또는 다른 것을 추가 할 때 실제로는 RDBMS 엔진에서만 쓸 수있는 내부 테이블 세트에 행을 추가하는 것입니다. DBA는 VIEW를 통해 데이터베이스를 조회하여 데이터베이스를 관리합니다. 오라클, IBM, MS 등이 전문가이기 때문에 이것이 최선의 방법이라고 말하면 우리는 그들의 리드를 따라야 할 것 같습니다. 각 애플리케이션 버전에 대한 VIEW 세트를 작성하십시오. 개발자가 만들고자하는 테이블 (일반적으로 상당히 비정규 화 된 테이블)을 따라 모델링하여 데이터가 손상되지 않도록 적절히 정규화 할 수 있습니다.
DocSalvager

감사. 이것에 대해 생각해야합니다. 주 도메인에서 모든 상태 지속 논리를 완전히 제거하는 ORM 계층을 응용 프로그램에 작성 중입니다. 서버 측 프로그래밍에 더 기반을두기 때문에 DB 관리 측보다 그 측면에서 더 많은 문제를 해결하는 경향이 있습니다. 현재의 전략을 사용하여 Db는 ORM이 원시 테이블을 적극적으로 관리하면서 상당히 평평했습니다. 테이블 뷰 및 가능하면 트랜잭션 로그를 추가하면 ORM에 더 많은 복잡성이 추가되지만 데이터 분할없이 여러 스키마 버전을 지원할 수 있습니다.
Marvin
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.