기금넷 공식사이트 - 재경 문답 - 소프트웨어 시스템에 대한 어느 정도의 이해

소프트웨어 시스템에 대한 어느 정도의 이해

이 기사는 시스템 소프트웨어에 대한 나의 이해 중 일부를 표현하기 위한 것입니다. 스타일은 이전 것과 다르며 전체적인 스타일은 더 "후퇴"입니다. 사실 나는 '후퇴'를 잘 하지 못하고, 조금 거부감도 든다. 나는 논문을 읽는 것보다 코드를 읽는 것을 선호하지만, 상대적으로 덜 읽는 편이다. 저는 졸업 이후 데이터베이스 스토리지 엔진 분야에서 일해 왔으며 지난 5년 동안은 Alibaba가 자체 개발한 LSM-Tree 스토리지 엔진 X-Engine의 연구 개발에 주력해 왔습니다. X-Engine의 클라우드 네이티브 아키텍처 업그레이드가 완료되어 상용화되었으므로 일정 규모의 고객을 수용하고 퍼블릭 클라우드에서 안정적으로 운영할 수 있습니다. 또한 이를 기반으로 클라우드 네이티브 기능을 구현하는 업계 최초의 TP 스토리지 엔진이 될 것입니다. LSM-트리 아키텍처. TP 스토리지 엔진의 아키텍처 기획, 설계 및 개발, 구현, 안정적인 운영 및 유지 관리의 전 과정을 완벽하게 겪었으며, 고위급 팀과 기술 리더 및 팀 전체의 우수한 엔지니어링 작업의 혜택을 받았습니다. 데이터베이스 분야에 입문한 이후로 능력과 기술적 비전, 그리고 그 과정에서 내 생각도 어느 정도 단계적으로 형성됐다. 또한, 업계의 뛰어난 설계자 및 엔지니어들과 대화를 나누면서 시스템 엔지니어링에 대한 이해에 대해 많은 의견이 있다는 것을 알게 되었고, 매우 귀중한 조언도 많이 받았습니다. 물론, 다른 의견도 있습니다. 이것이 제가 이 글을 쓰게 된 주된 이유이기도 합니다. 저는 이러한 의견이 패션이나 혁신이 아니라 제 자신의 생각과 경험에 대한 것임을 명확하게 표현하고 싶습니다.

관점 1: 소프트웨어의 본질은 하드웨어 리소스의 소비입니다. 서로 다른 소프트웨어의 차이점은 어떤 문제를 해결하기 위해 하드웨어 리소스가 소비되는지, 하드웨어 리소스 소비가 어떻게 할당되는지에 있습니다. "추상화"와 "절충점"은 소프트웨어 아키텍처 설계에서 자주 언급됩니다. 추상화는 본질적으로 "어떤 문제를 해결해야 하는가"를 의미하고, "절충점"은 실제로 "하드웨어 자원을 할당하는 방법"을 의미합니다. 예를 들어 TP 스토리지 엔진과 AP 스토리지 엔진은 행 스토리지 VS 컬럼 스토리지, 보조 인덱스 VS ZoneMap 인덱스, 강력한 트랜잭션 VS 약한 트랜잭션 등 구현상의 많은 차이점을 나열할 수 있습니다. 이러한 차이는 실제로 결과입니다.

1) 두 가지 문제를 해결하는 방법은 주로 온라인 실시간 서비스입니다. 상대적으로 크고(실제로 온라인으로 처리해야 하는 데이터, 기록 데이터가 많을 수 있음), 짧고 빠른 요청, 명확한 데이터 지역성, 높은 동시성 및 낮은 대기 시간 등, AP의 전체 데이터 규모 시나리오가 크고, 컴퓨팅 밀도가 높고, 처리량이 높습니다. (어떤 문제가 해결되는지)

2) TP 엔진의 완벽한 트랜잭션 지원은 비즈니스의 동시성 제어를 단순화합니다. 실제로 TP 엔진은 비즈니스 시스템이 원래 해야 하는 작업을 수행합니다. 이는 TP 엔진이 이를 위해 일부 하드웨어 리소스를 소비해야 함을 의미합니다. 데이터베이스에 데이터를 입력하는 속도를 높이기 위해 AP 엔진은 트랜잭션 지원이 상대적으로 약합니다. 이 부분의 작업은 여전히 ​​비즈니스 시스템(예: ETL)에 의해 완료되므로 이를 위해 하드웨어 리소스를 소비할 필요가 없습니다. . (하드웨어 자원 할당 방법) 관점 2: 시스템 소프트웨어의 큰 변화는 기본적으로 하드웨어 개발에 의해 주도된다. 이는 1)의 내용과 일치한다. 21세기에 들어서기 전에 학계에서는 시스템 소프트웨어 분야에서 이론에 대해 광범위하고 심도 있는 연구를 진행해 왔다. 초기의 컴퓨터 등장부터 메인프레임과 미니컴퓨터, 가정용 PC와 저렴한 범용 서버, 그리고 현재의 클라우드 컴퓨팅 IAAS 서비스에 이르기까지 기본적으로 시스템 소프트웨어의 개발은 이러한 추세를 따르고 있습니다. 시스템 소프트웨어의 새로운 인기는 본질적으로 IAAS의 "새로운 하드웨어"에 의해 주도되었습니다. 전체 IAAS의 온디맨드 인수는 제한된 물리적 리소스의 맥락에서 많은 이전 시스템 소프트웨어 설계를 깨뜨립니다. 이것이 바로 클라우드 네이티브 시스템 소프트웨어가 새로운 기회를 열어줄 것입니다. 관점 3: 다른 아키텍처보다 완전히 앞서는 시스템 아키텍처는 거의 없습니다. 이는 1)과 2)를 반영합니다. 다른 아키텍처 선택 뒤에는 서로 다른 상충 관계가 있습니다. 즉, 이익과 손실이 있어야 합니다. 이런 말을 자주 듣습니다. 이 논문과 이 기사를 보면 그들의 아키텍처에는 특별한 문제가 없지만 우리 아키텍처에는 이러한 문제가 있습니다.

이러한 견해를 들었을 때 나의 첫 번째 반응은 이에 대한 세 가지 주요 이유였습니다.

1) 많은 논문과 기사의 실험 결과는 재현될 수 없습니다. 그의 결론에 문제가 있다

2) '득점' 부분만 강조되고 '포기' 부분은 논의되지 않는 경우가 많다.

3) 우리 시스템의 문제가 미치는 영향의 정도와 문제의 해결 가능 여부를 판단하려면 정량적 데이터가 필요합니다. 다양한 논문이나 기사의 결론에 쉽게 영향을 받는다면 설명이 없는 시스템을 만들 가능성이 높습니다. 다양한 종파에서 무예를 배우는 무술수련생처럼, 결국 집착하기 쉽습니다. 관점 4: 모든 길은 로마로 통한다. 시스템의 최종 외관의 차이는 건축적 이유보다는 엔지니어링 구현에 더 가깝다. 다양한 시스템 아키텍처가 해결해야 하는 대부분의 문제는 본질적으로 동일하며, 시스템을 구성하는 구성 요소는 유사하므로 필요에 따라 시스템을 구축할 구성 요소를 선택하면 됩니다. 상황에 몰입하고 문제를 진정으로 직면하고 분석하고 해결해야만 본질을 이해할 수 있습니다. 그렇지 않으면 쉽게 종이에 말하는 것으로 변할 것입니다. 예를 들어, LSM-Tree 아키텍처에서 지속적으로 데이터를 쓸 때 성능에 큰 영향을 미치는 압축 문제에 대해 자주 질문을 받습니다. 이 문제를 이렇게 봅니다. 우선, LSM-Tree 아키텍처의 쓰기 삼키기 장점 중 하나는 innodb와 같은 디스크에 비해 B+ 트리는 쓰기 시 직접 정렬(페이지 순서가 지정됨, global Ordered), LSM-Tree 아키텍처는 정렬의 일부를 압축 정렬, 읽기 정렬로 전송하도록 선택합니다. 이는 기본적으로 쓰기 중 정렬 리소스 소비를 압축 또는 읽기로 전송합니다. 더티 플러시는 실제로 더티 페이지 생성과 더티 페이지를 디스크로 플러시라는 두 가지 작업으로 구성됩니다. Innodb는 쓰기 시 더티 페이지를 생성하는 것과 동일하며, 더티 페이지를 비울 때는 간단한 IO 작업입니다. 압축은 실제로 "더티 페이지"와 "더티 페이지"를 동시에 생성하여 디스크를 플러시합니다. innodb가 계속해서 쓰기를 하는 경우, 데이터가 제때 플러시되지 않으면 쓰기 성능에 영향을 미칠 수 있는 문제도 있을 것입니다. innodb 플러싱과 압축이 문제가 되는 이유는 본질적으로 메모리와 디스크 쓰기 속도의 차이로 인해 생산자-소비자 모델의 불균형이 발생하기 때문입니다. 따라서 innodb의 정리와 LSM-Tree의 압축은 본질적으로 동일한 문제이지만 이 프로세스가 시스템에 미치는 영향을 최소화하기 위해 서로 다른 방법을 사용합니다.

다음 내용은 제가 세부적인 디자인을 할 때 더 중요하다고 생각하는 원칙에 대한 내용을 주로 담고 있습니다. 이러한 원칙의 원리는 실제로 매우 이해하기 쉽고 "소프트웨어 공학"이라는 주제로 충분히 연구되었지만 실제로 구현하기에는 역사적 수하물이나 외부 환경으로 인해 상당히 어려울 수 있습니다. 실제 상황에 따라 다양한 절충안을 마련합니다. 우리가 하는 절충안은 신중하게 고려되어야 하며 성급하지 않아야 한다는 점은 주목할 가치가 있습니다. 그렇지 않으면 "결정"되기 쉽습니다. 또한 이러한 원칙을 준수하여 설계 및 구현된 시스템과 이러한 원칙을 완전히 준수하지 않고 설계 및 구현된 시스템의 결과는 실제로 "좋음과 더 나은 것의 차이"이지만 "얼마나 더 나은가"의 양은 실제로 시스템이 구축되기 전에는 측정하기가 어렵습니다. 이 7가지 원칙은 독립적으로 존재하는 것이 아니라 서로 보완적으로 존재합니다. 시나리오 지향: 우선 우리가 해결하려는 문제가 무엇인지 명확히 해야 합니다. 이것이 전체 시스템 구축의 출발점입니다. 모든 시스템에 맞는 단일 크기는 과거에도 존재하지 않았으며 미래에도 존재하지 않을 수 있습니다. 시스템의 개선은 지속적인 반복을 통해 완성되어야 하기 때문에 반복을 어떻게 하느냐가 본질적으로 그 단계에서 어떤 문제를 해결하느냐 하는 것입니다. 시스템은 많은 문제를 해결하기 위한 야심찬 목표를 가질 수 있지만, 향후 발전과 확장을 위한 기반을 유지하면서 요구 사항을 신속하게 충족할 수 있도록 모든 문제에 대한 로드맵은 계획에서 상대적으로 명확해야 합니다. 실제 연구 및 개발 과정에서 발생할 수 있는 두 가지 유형의 오류는 다음과 같습니다.

1) 전체 반복의 요구 사항을 충족하기 위해 엔지니어링 관리에 민첩한 개발 방법을 사용하고 싶습니다. 본질적으로 애자일 개발은 최소한의 기능 집합을 먼저 정의합니다. 즉, 먼저 어떤 문제를 해결해야 할지 명확하게 생각한 다음 빠르게 반복적으로 기능을 확장하는 것입니다. 이는 마치 작은 걸음으로 빠르게 걷는 것과 같습니다.

실제로 애자일 개발을 '빠르고, 거칠고, 치열한'으로 바꾸기는 쉽다. 이는 마치 미국을 따라잡기 위해 30일 동안 열심히 일하는 것과 같은 느낌이다.

2) 문제 정의가 명확하지 않으면 시스템의 "불변" 설정이 성급해지기 쉽습니다. 각 시스템에는 일부 "불변"이 있으며 이후 이러한 불변을 기반으로 많은 설계가 개발됩니다. 예를 들어 LSM-Tree 시스템의 일반적인 "불변"은 여러 버전이 있는 경우 업데이트된 데이터 버전이 더 낮은 수준에 있다는 것입니다. 동일한 데이터 행이 memtable, level0 및 level1에 동시에 존재하는 경우 memtable의 해당 버전은 최신 버전이어야 하며 level0의 버전도 level1의 버전보다 최신 버전이어야 합니다. 반복 프로세스 중에 이전에 설정된 "불변"이 비합리적인 것으로 밝혀지면 변경 비용이 매우 높아집니다. 디커플링 지향: 하향식이든 상향식이든 시스템을 설계하든 매우 중요한 사고 논리는 모듈 간의 결합을 최소화하는 것입니다. 잘 분리된 시스템은 다음을 의미하는 경우가 많습니다.

1) 각 모듈의 기능이 명확하게 고려되고 솔루션의 완성도가 상대적으로 높습니다.

2) 다음을 수행하는 데 도움이 됩니다. 특정 모듈을 보다 효율적으로 구현하는 데 중점을 두고 다른 모듈의 영향을 피합니다.

3) 후속 반복에 도움이 되고 영향을 제어할 수 있습니다.

4) 문제가 더 쉽습니다. 단일 모듈의 문제는 모듈 간에 문제가 전달된 후에 해결하기가 더 쉽습니다. 예를 들어 모듈 A에서 문제가 발생하면 모듈 B, C, D를 거쳐 문제가 발생합니다. 마지막으로 모듈 E가 노출됩니다. 일부 회의적인 관점에서는 디커플링을 위한 설계가 시스템의 전체 성능을 희생할 수 있다고 말합니다. 실제로 이는 처음부터 성능을 위해 과도하게 설계하지 않는 것과 같습니다. 일부 디커플링 설계가 실제로 성능에 영향을 미치는 경우 디커플링을 수행해야 합니다. 두 개의 모듈을 함께 결합하는 것은 함께 결합된 두 개의 모듈을 분해하는 것보다 덜 어려운 경우가 많습니다. 방어 지향: 호출된 함수가 잘못될 수 있다는 것을 가정합니다. 예를 들어 메모리 할당이 잘못될 수 있고, 기본 라이브러리 호출이 잘못될 수 있습니다. 문제가 발생하는지 고려하십시오. 시스템의 동작은 무엇입니까? '실패 중지'라는 매우 간단한 원칙이 있습니다. 완전한 방어가 이루어지지 않으면 실패하더라도 즉시 중지하기 어려워 결국 매우 이상한 현상이 발생하게 됩니다. 일반적인 의심은 다음과 같습니다.

1) 이 함수의 논리는 확실히 실패하지 않을 것임을 알 수 있습니다. 아마도 현재 관점에서 볼 때 이 함수가 실제로 실패하지 않을 수도 있지만, 반복을 통해 논리가 증가함에 따라 나중에 실패할 가능성이 없다고 보장하기는 어렵습니다.

2) 방어가 너무 많이 추가되면서 실제 논리 코드보다 방어 코드가 많아 성능에 영향을 미치게 됩니다. 우선, CPU의 현재 분기 예측 기능은 기본적으로 방어 코드가 대부분의 경우 성능에 영향을 미치지 않도록 보장할 수 있습니다. 또한, 결합에 대한 의문과 마찬가지로 일부 방어 코드가 성능 병목 현상이 발생한다면 최적화를 최적화해야 합니다. 방어를 최적화하는 것은 방어 없이 발생한 문제를 해결하는 것보다 항상 저렴합니다. 테스트 지향: 테스트 단계에서 문제를 해결하는 데 드는 비용은 프로덕션 환경에서 문제를 해결하는 데 드는 비용보다 훨씬 낮으므로 시스템을 테스트 가능하게 만드는 것이 매우 중요합니다. 시스템이 테스트 가능하다는 표준은 단위 테스트와 통합 테스트를 쉽게 수행할 수 있고 대부분의 코드 경로를 포괄할 수 있어야 한다는 것입니다. 지속적인 반복을 통해 테스트 가능한 시스템은 점점 더 많은 테스트 사례를 축적하여 안정성 기반을 지속적으로 강화합니다. 테스트 지향, 디커플링 지향, 방어 지향은 서로 보완적입니다. 모듈 간의 결합도가 충분히 낮은 경우에만 더 많은 테스트를 수행할 수 있습니다. 그렇지 않으면 모듈을 테스트하려면 많은 지저분한 작업이 필요합니다. 방어 지향적이면 테스트 동작을 더 잘 예측할 수 있습니다. 그렇지 않으면 비정상적인 매개변수가 입력되고 특정 실패가 불확실한 경우 테스트 케이스를 작성하기가 어려워집니다. 운영 및 유지 관리 중심: 복잡한 시스템의 경우 초기 단계에서 아무리 많은 준비를 해도 프로덕션 환경에서는 알 수 없는 문제를 피하기가 어렵습니다. 운영 및 유지 관리의 주요 목적은 문제가 발생할 때 적시에 손실을 막기 위해 가장 저렴한 방법을 사용하는 것입니다. 온라인 문제가 발생하면 다시 시작하여 해결하는 것보다 매개변수를 동적으로 조정하여 해결하는 것이 더 저렴하고, 버전을 출시하는 것보다 다시 시작하여 해결하는 것이 더 저렴합니다.

O&M 지향은 단지 몇 가지 매개변수나 스위치를 추가하는 것만큼 간단하지 않지만 문제가 발생할 경우 O&M 수단이 있는지 확인하기 위해 "O&M 지향"을 설계 계획의 중요한 부분으로 고려해야 합니다. 그것을 사용하고 나면 효과가 있을 것입니다. 문제의 본질에 지향: 문제를 해결할 때 문제의 본질적인 원인을 더 많이 생각해야 합니다. 간단한 문제는 본질을 파악하지 못하기 때문에 복잡해지고 복잡한 문제는 단순화됩니다. 그 이면에 있는 본질적인 이유를 명확하게 생각할 수 있다면 소스에서 이를 피하는 것이 더 철저한 해결책입니다. 그렇지 않으면 지속적인 패치 상태에 빠지기 쉽습니다. 나는 항상 "실패하면"이라는 관점을 가지고 있었습니다. 문제의 본질을 파악하여 문제를 해결하면 그 결과는 종종 문제를 만드는 것이 됩니다." 또 다른 경험으로는 모듈에 연속으로 문제가 여러 번 발생하면 초기 설계에서 개선이 필요한 부분이 있는지 생각해 봐야 한다는 것입니다. 시각화 지향: 시각화의 주요 목표는 시스템 작동 상태를 보다 직관적인 형태로 표시하는 것입니다. 이는 시스템 튜닝 및 진단에 매우 중요합니다. 시스템이 비정상인 경우 시각화를 통해 시스템의 문제를 빠르게 찾는 데 도움이 될 수 있습니다. 한편, 모니터링 시스템이 기록 상태를 추적할 수 있는 인터페이스를 제공할 수 있습니다. 예를 들어 Oracle의 진단 모니터링은 매우 좋은 사례이고 SnowFlake의 내부 상태 관리 및 모니터링은 거의 미친 수준입니다.

그런데 시스템은 궁극적으로 코드 라인으로 구현됩니다. 시스템을 구축하기 위해 독창성과 엄격함, 진정한 태도를 유지하는 것은 매우 간단하고 올바른 일이지만, 또한 매우 어렵습니다. 하세요.* **미안!

원본 링크: /m/1000349863/