다운 타임 제로 구축 달성


40

가동 중지 시간이없는 배포를 달성하려고 노력하여 근무 외 시간에는 더 적게 배포하고 "느린"시간에는 이론적으로 더 많이 배포 할 수 있습니다.

내 현재 설정은 다소 단순화되었습니다.

  • 웹 서버 A (.NET 앱)
  • 웹 서버 B (.NET 앱)
  • 데이터베이스 서버 (SQL Server)

내 현재 배포 프로세스 :

  1. 웹 서버 A와 B의 사이트를 "중지"
  2. 배포중인 앱 버전에 대한 데이터베이스 스키마 업그레이드
  3. 웹 서버 A 업데이트
  4. 웹 서버 B 업데이트
  5. 모든 것을 다시 온라인으로 가져 오십시오

현재 문제

이로 인해 매월 소량의 다운 타임이 발생합니다 (약 30 분). 나는 근무 외 시간 에이 작업을 수행하므로 큰 문제는 아니지만 내가 멀리하고 싶은 것입니다.

또한 실제로 '돌아갈'방법은 없습니다. 롤백 DB 스크립트를 만들지 않고 업그레이드 스크립트 만 만듭니다.

로드 밸런서 활용

한 번에 하나의 웹 서버를 업그레이드 할 수 있기를 바랍니다. Web Server A를로드 밸런서에서 꺼내고 업그레이드 한 후 다시 온라인으로 전환 한 다음 Web Server B에 대해 반복하십시오.

문제는 데이터베이스입니다. 내 소프트웨어의 각 버전은 다른 버전의 데이터베이스에 대해 실행해야하므로 일종의 "고착"상태입니다.

가능한 해결책

현재 고려중인 솔루션은 다음 규칙을 채택하는 것입니다.

  • 데이터베이스 테이블을 삭제하지 마십시오.
  • 데이터베이스 열을 삭제하지 마십시오.
  • 데이터베이스 열의 이름을 바꾸지 마십시오.
  • 열을 다시 정렬하지 마십시오.
  • 모든 저장 프로시 저는 버전이 지정되어야합니다.
    • 의미- 'spFindAllThings'는 편집시 'spFindAllThings_2'가됩니다.
    • 그런 다음 다시 편집하면 'spFindAllThings_3'이됩니다.
    • 뷰에도 동일한 규칙이 적용됩니다.

그러나 이것은 약간 극단적 인 것처럼 보입니다. 문제를 해결한다고 생각합니다. 각 버전의 응용 프로그램은 끊임없는 방식으로 DB에 충돌합니다. 코드는 뷰 / 저장 프로 시저의 특정 결과를 예상하며 '계약'을 유효하게 유지합니다. 문제는 단지 부주의 한 것 같습니다. 앱이 잠시 배포 된 후 오래된 저장 프로 시저를 정리할 수 있지만 더럽게 느껴집니다. 또한-이 규칙을 따르는 모든 개발자에게 달려 있으며, 대부분의 경우에 발생하지만 누군가 실수를 저지를 것입니다.

마지막으로-내 질문

  • 이 조잡하거나 해킹입니까?
  • 다른 사람이 이런 식으로하고 있습니까?
  • 다른 사람들이이 문제를 어떻게 해결하고 있습니까?

2
철회 계획은 어디에 있습니까? 모든 것이 작동하고 회귀가 없는지 어떻게 테스트합니까?
사슴 사냥꾼

3
"필요하지 않음"필요 없음 : 인접한 두 버전을 모두 동시에 실행할 수 있도록 "만"해야합니다. 이렇게하면 업그레이드 경로가 제한되지만 DB 스키마를 크게 변경할 수없는 정도는 아닙니다.
Joachim Sauer

감사합니다 Joachim ... 나는 기본 아이디어가 명확하도록 절대적으로 이야기하고 싶습니다. 그러나 당신은 맞습니다. 우리는 N 릴리스와 호환되는 정책을 가질 수 있습니다.이 시점에서 불필요한 DB 객체를 제거 할 수 있습니다.
MattW

2
롤백 계획을 세우고 싶을 것입니다. 어느 날 당신은 그것을 필요로 할 것입니다.
Thorbjørn Ravn Andersen 님이

1
내 경험상 대부분의 웹 사이트에서 가능한 해결책은 해결하는 문제보다 나쁩니다. 추가로 인해 복잡성이 예상보다 더 비쌉니다. 아마도 몇 배나 더 많은 시간과 노력으로 변경하고 기능을 추가 할 수 있습니다. 난 단지 절대적으로 할 수없는 웹 사이트에 대한 그것을 생각 하는데요 어떤 , 다운 타임이 이제까지 .
MGOwen

답변:


14

이것은 데이터베이스 기반 소프트웨어 업그레이드에 대한 실용적인 방법입니다. 이것은 2003 년 Martin Fowler와 Pramod Sadalage에 의해 설명 되었고, 그 후 리팩토링 데이터베이스 : Evolutionary Database Design에 작성되었습니다 .

나는 그것이 너절하게 보인다고 말할 때 당신이 의미하는 것을 볼 수 있지만, 의도적으로 그리고 미리 생각하고, 더 이상 사용되지 않을 때 코드베이스와 데이터베이스에서 사용되지 않는 구조를 리팩토링하는 데 시간이 걸리면, 그것은 더 강력합니다. 업그레이드 및 롤백 스크립트를 기반으로 한 더 간단한 솔루션.


5

"제로 다운 타임"은 이러한 접근 방식에 대한 여러 가지 가능한 이유 중 하나 일뿐입니다. 이 방법으로 데이터 모델을 이전 버전과 호환 가능하게 유지하면 많은 다른 문제를 처리하는 데 도움이됩니다.

  • 데이터베이스에 액세스하는 소프트웨어 패키지가 많은 경우 스키마 변경이 데이터베이스에 영향을 미치는지 모두 확인하지 않아도됩니다 (여러 팀이 같은 데이터베이스에 액세스하는 프로그램을 작성하는 여러 팀이있는 조직에서는 스키마 변경이 매우 어려워 질 수 있습니다)

  • 필요한 경우, 프로그램 중 하나의 이전 버전을 체크 아웃 할 수 있으며 (이전 프로그램이 새 컬럼을 올바르게 처리 할 것으로 예상하지 않는 한) 새 데이터베이스를 다시 실행할 것입니다.

  • 아카이브 된 데이터를 현재 데이터베이스 버전으로 가져 오기 / 내보내기가 훨씬 쉽습니다.

다음은 목록에 대한 추가 규칙입니다.

  • 각각의 새 열은 NULL을 허용하거나 의미있는 기본값을 제공해야합니다.

(이것은 새로운 열을 모르는 오래된 프로그램조차도 데이터베이스에서 새 레코드를 만들 때 아무것도 깨뜨리지 않도록합니다).

물론이 방법에는 한 가지 단점이 있습니다. 시간이 지남에 따라 데이터 모델 품질이 저하 될 수 있습니다. 또한 데이터베이스에 액세스하는 모든 응용 프로그램을 완벽하게 제어하고 열의 이름을 바꿀 때 모든 응용 프로그램을 쉽게 리팩토링 할 수 있다면 더 깔끔한 방식으로 리팩토링하는 것이 좋습니다.


4

배포마다 다릅니다.

물론 테이블이나 열을 삭제할 수는 없습니다. 인터페이스 호환성을 깨뜨린 것은 절대 바꿀 수 없습니다. 언제든지 추상화 계층을 추가 할 수 있습니다. 그러나 그 추상화와 버전을 버전 화해야합니다.

스스로 물어봐야 할 질문은 모든 단일 릴리스가 이전 버전과 호환되지 않는 방식으로 스키마를 변경하는 것입니까?

그런 식으로 스키마를 변경하는 릴리스가 거의없는 경우 데이터베이스 문제는 무시됩니다. 애플리케이션 서버를 지속적으로 배치하십시오.

가동 중지 시간을 최소화하면서 가장 도움이되는 두 가지 사항은 다음과 같습니다.

  1. 최소한 단일 릴리스 내에서 이전 버전과의 호환성을 위해 노력하십시오. 항상 달성 할 수는 없지만, 특히 각 릴리스가 작은 경우 90 % 이상의 릴리스에서 달성 할 수 있습니다.
  2. 시험판 및 시험판 데이터베이스 스크립트가 있어야합니다. 이를 통해 앱 코드가 배포되기 전에 새 개체를 만든 다음 앱 코드가 배포 된 후 이전 개체를 삭제하여 이름 변경 또는 인터페이스 변경을 처리 할 수 ​​있습니다. Null을 허용하지 않는 새로운 열을 추가하는 경우 기본값을 채우는 트리거를 사용하여 시험판 스크립트에서 Null을 허용하는 열로 추가 할 수 있습니다. 그런 다음 릴리스 후 트리거를 삭제할 수 있습니다.

유지 관리 기간 동안 나머지 배포를 저장할 수 있기를 바랍니다.

가동 중지 시간이 필요한 몇 가지 배포를 처리하는 데 도움이되는 다른 아이디어 :

  • 코드와의 호환성을 빌드 할 수 있습니까? 예를 들어, 코드에서 여러 유형의 결과 집합을 지원할 수있는 방법이 있습니까? int에서 double로 열을 변경 해야하는 경우 앱 코드는 열을 문자열로 읽고 구문 분석 할 수 있습니다. 일종의 해키이지만 릴리스 프로세스를 거치는 것이 임시 코드라면 세상의 끝이 아닐 수도 있습니다.
  • 저장 프로시 저는 스키마 변경으로부터 앱 코드를 격리하는 데 도움이됩니다. 이것은 지금까지만 갈 수 있지만 약간 도움이됩니다.

2

약간의 추가 노력으로 잠재적으로 이와 같이 할 수 있습니다.

  1. 내보내기를 수행하여 데이터베이스 백업
  2. 백업을 가져 오지만 myDb_2_1과 같은 릴리스 버전으로 이름을 바꿉니다.
  3. myDB_2_1에서 데이터베이스 릴리스 실행
  4. 웹 서버 A에서 앱 풀을 "중지"하거나로드 밸런서에서 제거
  5. 웹 서버 A 업데이트, 사후 구현 테스트 실행 및 필요한 경우 롤백
  6. 세션 블리드 웹 서버 B 및 웹 서버 A를 루프 상태로 되돌리기
  7. 웹 서버 B를 업그레이드 한 다음로드 밸런서에 다시 설치

당연히 웹 업데이트에는 새로운 Db 스키마를 가리 키기 위해 새로운 구성 항목이 필요합니다. 한 달에 한 번 릴리스를 수행하고 하위 팀과 호환되지 않는 DB 변경을 실제로 얼마나 많이 수행하고 있습니까? 테스트를 통해이를 제어 할 수 있다면 가동 중지 시간이 없거나 5 분만에 자동 배포를 수행 할 수 있습니다.


1
백업을 저장 한 후 서버 A를 중지하기 전에 서버 A의 앱이 DB에 쓰면 어떻게됩니까? 항상 "취약점 창"이 있습니다. 이러한 쓰기는 유실되므로 허용되지 않을 수 있습니다.
sleske
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.