Bond 만나기, Microsoft Bond - 새로운 데이터 직렬화 프레임워크
게시 됨: 2022-03-11Microsoft Bond는 Microsoft에서 만든 도식화된 데이터를 위한 새로운 직렬화 프레임워크입니다.
데이터 직렬화가 가장 많이 사용되는 위치를 요약해 보겠습니다.
- 파일, 스트림, NoSQL 및 BigData의 데이터 지속성.
- 네트워크, IPC 등의 데이터 전송
일반적으로 이러한 애플리케이션은 스키마화된 데이터를 처리해야 합니다. 여기서 스키마는 다음을 의미합니다.
- 구조: 계층, 관계, 순서.
- 의미론적: 태어난 이후 몇 년 동안의 나이.
실제로 모든 데이터에는 기본적으로 프로그래밍 언어에서 암시적으로 정의되거나 지원되는 경우에도 스키마가 있습니다. 복잡한 데이터 구조와 관련하여 우리는 종종 다른 언어로 지원하는 데이터 전송 객체(DTO)와 IO를 담당하는 코드를 작성하게 됩니다. 성장하고 진화하는 즉시 이 모든 조각을 유지하는 것은 악몽이 됩니다. 여기에서 직렬화 프레임워크가 게임에서 승리합니다.
우선 모든 직렬화 프레임워크는 특정 프로그래밍 언어나 플랫폼에 구속되지 않는 데이터 스키마 정의에 대한 추상화를 정의합니다. 이 추상화를 DSL(도메인별 언어)이라고 합니다.
이러한 DSL이 있으면 특정 응용 프로그램에 대한 데이터 스키마를 정의할 수 있습니다. 정의는 여러 형식으로 표현될 수 있지만 직렬화 프레임워크는 DSL에 적합한 단일 형식을 지원하는 경우가 많습니다. 너무 복잡한? 다음은 잘 알려진 한 가지 예입니다. XSD 및 XML입니다.
XSD는 DSL을 정의하고 XML은 XSD 스키마와 일치하는 문서를 정의하는 데 사용됩니다(권장). 그러나 "xsd.exe"를 사용하여 XSD와 일치하는 DTO 클래스를 생성할 수도 있으므로 생성된 클래스는 또 다른 형식일 뿐입니다. DTO에서 XML을 생성할 수 있으며 그 반대의 경우도 마찬가지입니다. 의미 체계는 공통적이므로 XSD로 정의되므로 의미적으로 동일합니다. 요약하면 직렬화 프레임워크는 주어진 프레임워크에서 가장 잘 지원되는 특정 형식으로 데이터 스키마를 정의하는 데 사용하는 DSL을 제공합니다.
추상 데이터 스키마는 결국 프로그래밍 언어로 표현된 엔터티 집합으로 구체화됩니다. 모든 직렬화 프레임워크는 코드 생성기라는 특수 도구를 제공합니다.
클라이언트가 도식화된 데이터(DTO, 프록시 등)로 작업하는 데 필요한 대상 프로그래밍 언어에 대한 모든 지원 코드를 생성합니다. 이는 궁극적으로 강력한 형식의 언어에 필요하지만 오리 형식(동적) 언어의 경우 선택 사항일 수 있습니다. .
마지막으로 중요한 것은 유선상의 데이터 지속성입니다. 실제 데이터는 결국 원시 바이트(또는 텍스트)로 직렬화되고 역직렬화됩니다.
모든 데이터 직렬화 프레임워크는 여기에서 프로토콜이라고 하는 또 다른 추상화를 제공합니다. 프로토콜은 스키마에 따라 구조화된 데이터를 직렬화 또는 역직렬화하는 방법을 정의하는 일련의 규칙을 정의합니다. 각 프로토콜은 일반적으로 주어진 직렬화 프레임워크에서 지원하는 모든 프로그래밍 언어 및 플랫폼에 대해 구현됩니다. 지원하는 프로그래밍 언어/플랫폼이 많을수록 더 많은 구현을 제공해야 합니다.
프레임워크가 JSON 프로토콜을 기꺼이 지원한다고 상상해보십시오. 그런 다음 C#, C++, Windows, Linux 등을 위한 JSON 판독기/작성기를 제공해야 합니다.
모든 것을 종합하면 모든 최신 데이터 직렬화 프레임워크는 다음을 제공합니다.
- 추상화: DSL 및 프로토콜.
- 코드 생성 도구.
- 프로토콜 구현.
Microsoft Bond는 최신 데이터 직렬화 프레임워크입니다. 강력한 DSL 및 유연한 프로토콜, C++ 및 C#용 코드 생성기, Windows, Linux 및 Mac OS X용 효율적인 프로토콜 구현을 제공합니다.
몇 년 동안 Bond는 내부 전용 기술로 남아 있었지만 Microsoft Open Source 이니셔티브 덕분에 Bond는 GitHub: Microsoft Bond에서 사용할 수 있게 되었습니다.
데이터 직렬화 경쟁자
소프트웨어 대기업 간의 경쟁으로 인해 다음과 같은 직렬화 프레임워크가 등장했습니다.
- Google Inc. - Google 프로토콜 버퍼
- Facebook Inc. - 현재 Apache에서 관리하는 Thrift
- Apache Foundation 소프트웨어 - Avro
분명히, 그것들은 모두 호환되지 않으며, 이것들 중 하나를 사용하여 공개 API를 만들지 않는 한 괜찮습니다.
각각 장단점이 있으니 필요에 따라 선택하시면 됩니다.
왜 본드인가?
이 질문에 대한 공식 답변은 "Why Bond"입니다.
다음은 빠른 요약입니다.
- Bond는 제네릭을 포함한 풍부한 유형 시스템을 지원합니다.
- Bond는 스키마 버전 관리 및 양방향 호환성을 지원합니다.
- Bond는 런타임 스키마 조작을 지원합니다.
- Bond는 다양한 컬렉션을 지원합니다.
, 지도 , 목록 ". - Bond는 유형 안전 지연 직렬화를 지원합니다.
" - Bond는 마샬링 및 트랜스코딩을 통해 플러그형 프로토콜(형식)을 지원합니다.
중요한 점은 Bond가 "pay to play" 전략을 따른다는 것입니다. 추가/사용하는 기능이 많을수록 크기와 속도에 대해 더 많은 비용을 지불해야 합니다. 이는 개발자에게 뛰어난 유연성을 제공합니다.
솔직하게 단점도 나열해 보겠습니다.
- Bond는 C++ 및 C#을 지원하지만 Java(아직)는 지원하지 않는 Microsoft 스택을 목표로 하고 있습니다.
- Bond는 공용체 유형(protobuf의 "oneof")을 지원하지 않습니다.
성능은 어떻습니까?
한 프레임워크를 다른 프레임워크와 비교할 때 개발자는 종종 성능 비교를 찾습니다. 그러나 이러한 프레임워크가 DSL, 코드 생성기 및 프로토콜로 구성되어 있음을 기억합시다. 프로토콜 성능만 고려한다면 DSL과 codegen이 제공하는 기능을 놓치게 될 것입니다. 때로는 직렬화 속도에서 몇 퍼센트 차이가 나는 것보다 더 나은 DSL을 갖는 것이 훨씬 더 중요합니다.
속도 외에 일부 프로토콜에서 지원하는 공간 효율적인 인코딩도 중요할 수 있습니다. 도메인별 데이터와 성능/공간 비교를 수행하는 것이 좋습니다. 이것은 특정 프레임워크에서 얻을 수 있는 모든 이점을 추정하는 유일한 방법입니다.

이 기사는 Windows 응용 프로그램 이벤트 로그에서 모든 레코드를 읽고 Bond 개체로 직렬화하고 다시 역직렬화하여 Bond 프레임워크 사용을 보여주는 데모 프로젝트와 함께 제공됩니다.
데모를 빌드하고 실행하기 위해 Visual Studio 이외의 소프트웨어를 설치할 필요가 없습니다.
마이크로소프트 본드 사용
본드 얻기
귀하의 플랫폼에 대한 Bond를 얻는 방법에 대한 공식 가이드를 확인하십시오.
.NET 프로젝트의 경우 다음과 같이 간단합니다.
install-package Bond.CSharp
패키지에는 다음이 포함됩니다.
- bin 폴더의 코드 생성기(gbc.exe)
- .NET 라이브러리
- MSBuild 작업
워크플로
워크플로에는 다음 단계가 포함됩니다.
- ".bond" 파일을 작성하여 DSL을 배우고 데이터 스키마를 정의합니다.
- 코드 생성기("gbc.exe")를 사용하여 프로그래밍 언어에 대한 DTO를 가져옵니다.
- 프로젝트에서 생성된 파일과 Bond 런타임 라이브러리를 참조하십시오.
프레임워크와 함께 제공되는 MSBuild 작업을 사용하여 코드 생성 단계를 자동화하는 것이 좋습니다.
DSL 기능 개요
첫 번째 ".bond" 파일 작성을 시작할 때 해당 구문과 기능을 알아야 합니다. IDL을 자세히 설명하는 공식 문서 페이지를 방문하십시오. 기본적인 기능만 검토해 보겠습니다.
- 모듈: 스키마는 "가져오기" 문에 포함된 여러 파일로 분할될 수 있습니다.
- 네임스페이스: C++/C#과 동일한 의미를 갖습니다.
- 사용자 정의 구조체: 사용자 유형 정의의 단위.
- 순방향 선언은 재귀 데이터 구조에 유용합니다.
- 기본 유형: "bool, uint8(~64), int8(~64), float, double, string, wstring".
- 컨테이너 유형: "블롭, 목록
, 벡터 , 세트 , map<K, T>, null 허용 ". - 사용자 지정 유형 별칭 및 매핑, 예를 들어 C#에서 "DateTime"을 갖고 싶지만 유선에서 틱("int64")하는 경우.
- 사용자 정의 속성: 사용자 정의 코드 생성에 유용합니다.
지루한? 다음은 예입니다.
namespace MyProject struct MyRecord { 0: string Name = "Noname"; 1: vector<double> Constants; }
여기서 "0"과 "1"은 필드 서수(모든 정수가 될 수 있음)이고 = "Noname"
은 (선택 사항) 기본값입니다.
코드 생성
Bond 프레임워크는 Haskell로 작성된 코드 생성 도구를 제공합니다. 다음은 명령줄의 ".bond" 스키마에서 C# 및 C++ 코드를 생성하는 방법입니다.
gbc c# example.bond gbc c++ example.bond
지원되는 프로토콜(형식)
즉시 사용 가능한 Bond는 세 가지 종류의 프로토콜을 지원합니다.
- 태그가 지정된 프로토콜: "CompactBinary" 및 "FastBinary"
태그가 지정된 프로토콜은 페이로드 내에서 스키마 메타데이터를 인터리브합니다. 이렇게 하면 페이로드가 자체 설명되어 소비자가 생산자가 사용하는 스키마를 알지 못하더라도 해석할 수 있습니다.
- 태그 없는 프로토콜: "SimpleBinary"
태그가 지정되지 않은 프로토콜은 데이터만 직렬화하므로 소비자는 대역 외 메커니즘을 통해 페이로드 스키마를 알아야 합니다. 태그가 지정되지 않은 프로토콜은 스키마를 한 번(예: 데이터베이스의 시스템 테이블에) 저장할 수 있으므로 동일한 스키마를 사용하는 많은 레코드에서 메타데이터 오버헤드를 제거하기 때문에 스토리지 시나리오에서 자주 사용됩니다.
- DOM 기반 프로토콜: "SimpleJson" 및 "SimpleXml"
DOM 기반 프로토콜은 전체 페이로드를 메모리 내 데이터 개체 모델로 구문 분석한 다음 역직렬화 중에 쿼리됩니다. 일반적으로 이러한 종류의 프로토콜은 JSON 또는 XML과 같은 텍스트 기반 인코딩을 구현하는 데 사용됩니다.
각 프로토콜에 대해 Bond 런타임 라이브러리는 실제 직렬화 작업을 수행하는 해당 Reader 및 Writer 클래스를 제공합니다.
프로토콜을 사용하는 것은 매우 간단하고 유명한 "JsonConvert.SerializeObject()"보다 약간 어렵습니다.
var record = new MyRecord { Name = "FooBar", Constants = { 3.14, 6.28 } }; var output = new OutputBuffer(); var writer = new CompactBinaryWriter<OutputBuffer>(output); Serialize.To(writer, record); var input = new InputBuffer(output.Data); var reader = new CompactBinaryReader<InputBuffer>(input); record = Deserialize<Example>.From(reader);
무엇 향후 계획?
Bond를 사랑하고 코딩할 여가 시간이 충분하다면 이 항목 중 하나를 개발에 사용하는 것을 고려하십시오. 기여함으로써 얻을 수 있는 모든 이점을 열거하지는 않겠지만 많은 개발자가 다음과 같은 기여 아이디어를 찾고 있다는 것을 알고 있습니다.
- Java에 대한 포트를 구현합니다. Java를 원하는 다른 주류 언어로 교체하십시오.
- 다른 DSL(예: ".proto <=> .bond")과 교환하기 위해 Bond 스키마 가져오기/내보내기를 구현합니다.
Bond와 관련하여 무엇을 결정하든 먼저 Adam Sapek에게 연락하는 것이 좋습니다. 그는 이 프로젝트의 리더이며 시장이 가장 요구하는 것을 안내할 것입니다.