ADO.NET 조직 지속성
Orleans의 관계형 스토리지 백 엔드 코드는 제네릭 ADO.NET 기능을 기반으로 하며 결과적으로 데이터베이스 공급업체에 구애받지 않습니다. Orleans 데이터 스토리지 레이아웃은 이미 런타임 테이블에서 설명되었습니다. 연결 문자열 설정은 Orleans 구성 가이드에 설명된 대로 수행됩니다.
지정된 관계형 데이터베이스 백 엔드에서 Orleans 코드가 작동하도록 하려면 다음이 필요합니다.
- 적절한 ADO.NET 라이브러리를 프로세스에 로드해야 합니다. 애플리케이션 구성의 DbProviderFactories 요소를 통해 일반적인 방식으로 정의해야 합니다.
- 옵션의
Invariant
속성을 통해 ADO.NET 고정을 구성합니다. - 데이터베이스가 존재하고 코드와 호환되어야 합니다. 이 작업은 공급업체별 데이터베이스 생성 스크립트를 실행하여 수행됩니다. 자세한 내용은 ADO.NET 구성을 참조하세요.
ADO .NET 조직 스토리지 공급자를 사용하면 관계형 데이터베이스에 조직 상태를 저장할 수 있습니다. 현재 다음 데이터베이스가 지원됩니다.
- SQL Server
- MySQL/MariaDB
- PostgreSQL
- Oracle
먼저 기본 패키지를 설치합니다.
Install-Package Microsoft.Orleans.Persistence.AdoNet
해당 ADO.NET 고정 및 설치 스크립트를 포함하여 데이터베이스 구성에 대한 정보는 ADO.NET 구성 문서를 참조하세요.
다음은 ISiloHostBuilder를 통해 ADO.NET 스토리지 공급자를 구성하는 방법의 예입니다.
var siloHostBuilder = new HostBuilder()
.UseOrleans(c =>
{
c.AddAdoNetGrainStorage("OrleansStorage", options =>
{
options.Invariant = "<Invariant>";
options.ConnectionString = "<ConnectionString>";
options.UseJsonFormat = true;
});
});
기본적으로 데이터베이스 공급업체별 연결 문자열과 공급업체를 식별하는 Invariant
(ADO.NET 구성 참조)만 설정하면 됩니다. 이진(기본값), JSON 또는 XML이 될 수 있는 데이터가 저장되는 형식을 선택할 수도 있습니다. 이진 파일이 가장 컴팩트한 옵션이지만 불투명하며 데이터를 읽거나 작업할 수 없습니다. JSON이 권장되는 옵션입니다.
AdoNetGrainStorageOptions를 통해 다음 속성을 설정할 수 있습니다.
/// <summary>
/// Options for AdoNetGrainStorage
/// </summary>
public class AdoNetGrainStorageOptions
{
/// <summary>
/// Define the property of the connection string
/// for AdoNet storage.
/// </summary>
[Redact]
public string ConnectionString { get; set; }
/// <summary>
/// Set the stage of the silo lifecycle where storage should
/// be initialized. Storage must be initialized prior to use.
/// </summary>
public int InitStage { get; set; } = DEFAULT_INIT_STAGE;
/// <summary>
/// Default init stage in silo lifecycle.
/// </summary>
public const int DEFAULT_INIT_STAGE =
ServiceLifecycleStage.ApplicationServices;
/// <summary>
/// The default ADO.NET invariant will be used for
/// storage if none is given.
/// </summary>
public const string DEFAULT_ADONET_INVARIANT =
AdoNetInvariants.InvariantNameSqlServer;
/// <summary>
/// Define the invariant name for storage.
/// </summary>
public string Invariant { get; set; } =
DEFAULT_ADONET_INVARIANT;
/// <summary>
/// Determine whether the storage string payload should be formatted in JSON.
/// <remarks>If neither <see cref="UseJsonFormat"/> nor <see cref="UseXmlFormat"/> is set to true, then BinaryFormatSerializer will be configured to format the storage string payload.</remarks>
/// </summary>
public bool UseJsonFormat { get; set; }
public bool UseFullAssemblyNames { get; set; }
public bool IndentJson { get; set; }
public TypeNameHandling? TypeNameHandling { get; set; }
public Action<JsonSerializerSettings> ConfigureJsonSerializerSettings { get; set; }
/// <summary>
/// Determine whether storage string payload should be formatted in Xml.
/// <remarks>If neither <see cref="UseJsonFormat"/> nor <see cref="UseXmlFormat"/> is set to true, then BinaryFormatSerializer will be configured to format storage string payload.</remarks>
/// </summary>
public bool UseXmlFormat { get; set; }
}
ADO.NET 지속성은 데이터 버전을 지정하고 임의 애플리케이션 규칙 및 스트리밍을 사용하여 임의의 (역)직렬 변환기를 정의하는 기능을 가지고 있지만, 현재 애플리케이션 코드에 노출하는 방법은 없습니다.
ADO.NET 지속성 근거
ADO.NET 지원 지속성 스토리지의 원칙은 다음과 같습니다.
- 데이터, 데이터 형식 및 코드가 발전하는 동안 중요 비즈니스용 데이터를 안전하게 액세스할 수 있도록 유지합니다.
- 공급업체별 기능과 스토리지별 기능을 활용합니다.
실제로 이는 ADO.NET 구현 목표를 준수하고 스토리지의 데이터 형태를 발전시키는 ADO.NET 특정 스토리지 공급자에 구현 논리를 추가하는 것을 의미합니다.
ADO.NET 공급자는 일반적인 스토리지 공급자 기능 외에도 다음과 같은 기본 제공 기능을 제공합니다.
- 라운드트립 상태일 때 스토리지 데이터를 한 형식에서 다른 형식(예: JSON에서 이진으로)으로 변경합니다.
- 스토리지에서 저장하거나 읽을 형식을 임의 방식으로 셰이프합니다. 이렇게 하면 상태 버전이 진화할 수 있습니다.
- 데이터베이스에서 데이터를 스트리밍합니다.
1.
과 2.
둘 다 조직 ID, 조직 형식, 페이로드 데이터와 같은 임의의 의사 결정 매개 변수에 따라 적용할 수 있습니다.
직렬화 형식(예: SBE(Simple Binary Encoding))을 선택하고 IStorageDeserializer 및 IStorageSerializer를 구현할 수 있는 경우입니다. 기본 제공 직렬 변환기는 다음 메서드를 사용하여 빌드되었습니다.
- OrleansStorageDefaultXmlSerializer
- OrleansStorageDefaultXmlDeserializer
- OrleansStorageDefaultJsonSerializer
- OrleansStorageDefaultJsonDeserializer
- OrleansStorageDefaultBinarySerializer
- OrleansStorageDefaultBinaryDeserializer
직렬 변환기가 구현되면 AdoNetGrainStorage의 StorageSerializationPicker 속성에 추가해야 합니다. 다음은 IStorageSerializationPicker
의 구현입니다. 기본적으로 StorageSerializationPicker
이 사용됩니다. 데이터 스토리지 형식을 변경하거나 직렬 변환기를 사용하는 예제는 RelationalStorageTests에서 확인할 수 있습니다.
현재는 프레임워크에서 생성한 AdoNetGrainStorage
에 액세스할 메서드가 없으므로 serialization 선택기를 Orleans 애플리케이션에 노출할 메서드가 없습니다.
디자인의 목표
1. ADO.NET 공급자가 있는 백 엔드 사용 허용
여기에는 온-프레미스 설치의 요인인 .NET에 사용할 수 있는 가장 광범위한 백 엔드 세트가 포함되어야 합니다. 일부 공급자는 ADO.NET 개요에 나열되지만 Teradata와 같이 모든 공급자가 나열되는 것은 아닙니다.
2. 배포가 실행되는 동안에도 쿼리 및 데이터베이스 구조를 적절하게 조정할 수 있는 가능성을 유지합니다.
대부분의 경우 서버 및 데이터베이스는 클라이언트와의 계약 관계에 있는 제3자가 호스팅합니다. 가상화된 호스팅 환경을 찾는 것은 드문 일이 아니며 노이즈 네이버 또는 결함이 있는 하드웨어와 같은 예기치 않은 요인으로 인해 성능이 변동되는 경우입니다. 계약상의 이유로 Orleans 이진 파일 또는 애플리케이션 이진 파일을 변경하고 다시 배포하는 불가능할 수 있지만 일반적으로 데이터베이스 배포 매개 변수를 조정할 수 있습니다. Orleans 이진 파일과 같은 표준 구성 요소를 변경하려면 지정된 상황에서 최적화하기 위한 더 긴 절차가 필요합니다.
3. 공급업체별 및 버전별 기능을 활용할 수 있음
공급업체는 제품 내에서 다양한 확장 및 기능을 구현했습니다. 이러한 기능을 사용할 수 있을 때 사용하는 것이 좋습니다. PostgreSQL의 네이티브 UPSERT 또는 PipelineDB 및 SQL Server의 PolyBase 또는 고유하게 컴파일된 테이블 및 저장 프로시저와 같은 기능입니다.
4. 하드웨어 리소스 최적화 가능
애플리케이션을 디자인할 때 다른 데이터보다 더 빠르게 삽입해야 하는 데이터와 더 저렴한 콜드 스토리지에 넣을 수 있는 데이터(예: SSD와 HDD 간의 데이터 분할)를 예상하는 경우가 많습니다. 추가 고려 사항에는 데이터의 물리적 위치(일부 데이터가 더 비사거나(예: SSD RAID viz HDD RAID) 또는 더 안전할 수 있음) 또는 기타 의사 결정 기준이 포함됩니다. 지점 3과 관련하여 일부 데이터베이스는 SQL Server 분할 테이블 및 인덱스와 같은 특수 분할 체계를 제공합니다.
이러한 원칙은 애플리케이션 수명 주기 전체에 적용됩니다. Orleans 자체의 원칙 중 하나가 고가용성이라는 점을 고려하면 Orleans 배포를 중단하지 않고 스토리지 시스템을 조정할 수 있거나 데이터 및 기타 애플리케이션 매개 변수에 따라 쿼리를 조정할 수 있어야 합니다. Brian Harry의 블로그 게시물에서 동적 변화의 예를 볼 수 있습니다.
테이블이 작으면 쿼리 계획이 무엇인지는 거의 중요하지 않습니다. 보통인 경우 OK 쿼리 계획은 괜찮지만 엄청난 규모(수백만 개 또는 수십억 개의 행)인 경우 쿼리 계획의 약간의 변형으로도 종료할 수 있습니다. 이러한 이유로 중요한 쿼리를 많이 암시합니다.
5. 조직에서 사용되는 도구, 라이브러리 또는 배포 프로세스에 대한 가정 없음
많은 조직에서 Dacpac 또는 Red Gate와 같은 특정 데이터베이스 도구 세트에 대해 잘 알고 있습니다. 데이터베이스를 배포하려면 사용 권한 또는 DBA 역할을 수행하는 사용자와 같은 사람이 필요할 수 있습니다. 일반적으로 이는 대상 데이터베이스 레이아웃과 애플리케이션이 부하를 예측하는 데 사용하기 위해 생성하는 쿼리의 대략적인 스케치를 가지고 있음을 의미합니다. 스크립트 기반 배포를 의무화하는 업계 표준의 영향을 받는 프로세스가 있을 수 있습니다. 외부 스크립트에 쿼리 및 데이터베이스 구조가 있으면 이 작업을 수행할 수 있습니다.
6. ADO.NET 라이브러리 및 기능을 로드하는 데 필요한 최소 인터페이스 기능 세트 사용
이는 둘 다 빠르며 ADO.NET 라이브러리 구현 불일치에 노출되는 표면이 적습니다.
7. 디자인을 분할 가능으로 만들기
예를 들어 관계형 스토리지 공급자와 같이 적합한 경우 디자인을 쉽게 분할할 수 있도록 합니다. 예를 들어 이는 데이터베이스 종속 데이터(예: IDENTITY
)를 사용하지 않음을 의미합니다. 행 데이터를 구분하는 정보는 실제 매개 변수의 데이터만 기반으로 작성되어야 합니다.
8. 설계를 테스트하기 쉽게 만들기
새 백 엔드를 만드는 것은 대상을 지정하려는 백 엔드의 SQL 방언으로 기존 배포 스크립트 중 하나를 변환하고, 테스트에 새 연결 문자열을 추가하고(기본 매개 변수 가정) 지정된 데이터베이스가 설치되어 있는지 확인한 다음, 이에 대한 테스트를 실행하는 것만큼 쉽습니다.
9. 이전 사항을 고려하여 새 백 엔드에 대한 포팅 스크립트와 이미 배포된 백 엔드 스크립트를 가능한 한 투명하게 수정합니다.
목표 실현
Orleans 프레임워크는 배포 관련 하드웨어(활성 배포 중에 하드웨어가 변경될 수 있음), 배포 수명 주기 동안의 데이터 변경 또는 특정 상황에서만 사용할 수 있는 특정 공급업체별 기능에 대해 알지 못합니다. 이러한 이유로 데이터베이스와 Orleans 간의 인터페이스는 이러한 목표를 충족하고, 오용에 대해 견고하게 만들고, 필요한 경우 쉽게 테스트할 수 있도록 최소 추상화 및 규칙 세트를 준수해야 합니다. 런타임 테이블, 클러스터 관리 및 구체적인 멤버 자격 프로토콜 구현. 또한 SQL Server 구현에는 SQL Server 버전별 튜닝이 포함됩니다. 데이터베이스와 Orleans 간의 인터페이스 계약은 다음과 같이 정의됩니다.
- Orleans 특정 쿼리를 통해 데이터를 읽고 쓰는 것이 일반적인 아이디어입니다. Orleans는 읽을 때는 열 이름과 형식에 대해 작동하고 쓸 때는 변수 이름 및 형식에 대해 작동합니다.
- 구현은 입력 및 출력 이름 및 형식을 유지해야 합니다. Orleans는 이러한 매개 변수를 사용하여 이름 및 형식별로 쿼리 결과를 읽습니다. 공급업체별 튜닝 및 배포별 튜닝이 허용되며 인터페이스 계약이 유지되는 한 기여가 권장됩니다.
- 공급업체별 스크립트의 구현은 제약 조건 이름을 유지해야 합니다. 이렇게 하면 구체적인 구현에서 균일한 이름을 지정하여 문제 해결을 간소화할 수 있습니다.
- 버전 – 또는 애플리케이션 코드의 ETag – Orleans의 경우 고유한 버전을 나타냅니다. 실제 구현의 형식은 고유한 버전을 나타내는 한 중요하지 않습니다. 구현에서 Orleans 코드는 부호 있는 32비트 정수를 기대합니다.
- 명시적이고 모호성을 제거하기 위해 Orleans는 일부 쿼리가 TRUE as > 0 값 또는 FALSE as = 0 값을 반환할 것으로 예상합니다. 즉, 영향을 받거나 반환된 행의 수는 중요하지 않습니다. 오류가 발생하거나 예외가 throw되는 경우 쿼리는 전체 트랜잭션이 롤백되었는지 확인해야 하며 FALSE를 반환하거나 예외를 전파할 수 있습니다.
- 현재 하나의 쿼리를 제외한 모든 쿼리는 단일 행 삽입 또는 업데이트입니다(참고: 연결된
UPDATE
쿼리가 마지막 쓰기를 수행한 경우SELECT
쿼리를INSERT
로 대체할 수 있음).
데이터베이스 엔진은 데이터베이스 내 프로그래밍을 지원합니다. 이는 실행 가능한 스크립트를 로드하고 데이터베이스 작업을 실행하기 위해 호출하는 아이디어와 비슷합니다. 의사 코드에서는 다음과 같이 표시될 수 있습니다.
const int Param1 = 1;
const DateTime Param2 = DateTime.UtcNow;
const string queryFromOrleansQueryTableWithSomeKey =
"SELECT column1, column2 "+
"FROM <some Orleans table> " +
"WHERE column1 = @param1 " +
"AND column2 = @param2;";
TExpected queryResult =
SpecificQuery12InOrleans<TExpected>(query, Param1, Param2);
이러한 원칙은 데이터베이스 스크립트에도 포함됩니다.
사용자 지정된 스크립트 적용에 대한 몇 가지 아이디어
- 일부 조직 상태는 메모리 최적화 테이블을 사용하는 반면 일부 상태는 기본
INSERT
를 사용하여 저장되도록IF ELSE
가 있는 조직 지속성을 위해OrleansQuery
의 스크립트를 변경합니다. 그에 따라SELECT
쿼리를 변경해야 합니다. 1.
의 아이디어는SSD
또는HDD
간에 데이터 분할하거나, 암호화된 테이블에 일부 데이터를 배치하거나, SQL-Server-Hadoop 또는 연결된 서버를 통해 통계 데이터를 삽입하는 것과 같은 다른 배포 또는 공급업체별 측면을 활용하는 데 사용할 수 있습니다.
변경된 스크립트는 Orleans 테스트 도구 모음을 실행하거나 SQL Server 단위 테스트 프로젝트를 사용하여 데이터베이스에서 직접 테스트할 수 있습니다.
새 ADO.NET 공급자를 추가하기 위한 지침
- 위의 목표 실현 섹션에 따라 새 데이터베이스 설정 스크립트를 추가합니다.
- 공급업체 ADO 고정 이름을 AdoNetInvariants에 추가하고 ADO.NET 공급자별 데이터를 DbConstantsStore에 추가합니다. 일부 쿼리 작업에서 (잠재적으로) 사용될 수 있습니다. 예를 들어 올바른 통계 삽입 모드(예:
FROM DUAL
이 있거나 없는UNION ALL
)를 선택합니다. - Orleans는 멤버 자격, 미리 알림 및 통계와 같은 모든 시스템 저장소에 대한 포괄적인 테스트를 제공합니다. 새 데이터베이스 스크립트에 대한 테스트 추가는 기존 테스트 클래스를 복사하여 붙여넣고 ADO 고정 이름을 변경하여 수행됩니다. 또한 ADO 고정에 대한 테스트 기능을 정의하기 위해 RelationalStorageForTesting에서 파생됩니다.
.NET