트윈 시티 코드 캠프

분산 캐싱으로 .NET 애플리케이션 확장

이크발 칸
사장 및 기술 전도사

분산 캐시에 대한 실습 데모를 보고 다양한 환경에서 .NET 캐시를 사용하는 모범 사례를 알아보세요. 이 강연에서는 다음 내용을 다룹니다.

  • .NET 애플리케이션의 확장성 병목 현상에 대한 간략한 개요
  • 분산 캐싱에 대한 설명과 성능 문제를 해결하는 방법
  • 애플리케이션에서 분산 캐싱을 사용할 수 있는 위치
  • 분산 캐시의 몇 가지 중요한 기능
  • 분산 캐시를 사용한 실습 예제

살펴보기

와주신 모든 분들께 감사드립니다. 제 이름은 이크발 칸입니다. 밖은 아름다운 날입니다. 저는 탬파에서 왔습니다. 여기 온도가 훨씬 더 좋아요. 나는 여기보다 훨씬 더 시원한 날씨를 기대하고 있었습니다. 그러니 실내에 머물러 주셔서 감사합니다. 저는 이 회사의 기술 전도사입니다. Alachisoft. 우리는 NCache. 다음 XNUMX~XNUMX분 동안은 마케팅 설명이 될 것입니다. 따라서 .NET 공간을 위한 두 가지 제품이 있습니다. 하나는 당사의 주력 제품인 NCache 이는 .NET용 분산 캐시입니다. 그것이 바로 우리가 갖고 있는 전문성입니다. 그래서 우리는 약 10년 동안 이 분야에 종사해 왔으며 이것이 우리가 이 특정 주제에 대한 전문 지식을 구축한 방법입니다.

이라는 또 다른 제품이 있습니다. NosDB 이는 우리가 작년 말에 출시한 것입니다. 오픈 소스입니다 NoSQL database .NET용. MongoDB 수준 기능과 비슷하지만 기본 .NET과 다시 모두 오픈 소스입니다. NCache 오픈 소스이기도 하며, NosDB. 저희 제품을 한번 살펴보시기 바랍니다.

그래서 좀 더 쌍방향적인 토론을 하고 싶습니다. 우리는 몇 가지 아키텍처 개념 논의와 일부 소스 코드를 결합하여 살펴보겠습니다. 따라서 실제로 애플리케이션에 캐시를 사용하는 방법을 확인할 수 있습니다. 이제 시작하겠습니다.

확장성

몇 가지 정의를 살펴보겠습니다. 첫 번째는 다음과 같습니다. 확장성이란 무엇입니까? 확장성은 성능이 아닙니다. 따라서 애플리케이션이 5명의 사용자로 빠르게 수행되는 경우 5000명, 50,000명 또는 500,000명의 사용자 아래에서 동일한 우수한 성능을 가질 수 없다면 확장할 수 없습니다. 물론, 애플리케이션이 5명의 사용자를 대상으로 빠르게 작동하지 않는다면 우리가 설명할 내용 이외의 다른 측면도 살펴봐야 합니다.

선형 확장 성

선형 확장성은 배포 아키텍처 용어에 가깝습니다. 귀하의 애플리케이션이 더 많은 서버를 추가하여 용량, 트랜잭션 용량을 늘릴 수 있도록 설계되어 있다면 확장성이라는 단어를 사용할 때 주로 트랜잭션 용량에 대해 이야기하는 것이지 많은 것을 말하는 것이 아닙니다. 데이터. 따라서 확장성 측면에서 테라바이트 규모의 데이터를 말하는 것이 아닙니다. 우리는 많은 거래, 많은 활동을 처리할 수 있는지에 대해 이야기하고 있습니다. 따라서 선형 확장성은 서버를 추가하는 것만으로 트랜잭션 용량을 늘릴 수 있고 병목 현상이 없다는 것을 의미하며 이것이 우리가 달성하고자 하는 것입니다.

선형 확장 성

비선형 확장성

물론 비선형은 우리가 달성하고 싶은 것이 아닙니다. 즉, 추가하는 서버 수는 중요하지 않으며 특정 지점 이후에는 성능이 저하될 것입니다. 배포 시 애플리케이션 아키텍처에 몇 가지 근본적인 병목 현상이 있어 확장이 불가능하기 때문입니다.

비선형 확장성

어떤 애플리케이션에 확장성이 필요합니까?

확장성이 필요한 애플리케이션 유형은 무엇입니까? 이는 일반적으로 서버 유형의 응용 프로그램인 ASP.NET, ASP입니다..NET Core 이제 일반적으로 WCF인 웹 서비스, 반드시 그럴 필요는 없지만 일반적으로 웹 서비스인 IoT 백엔드입니다. 빅 데이터 처리 애플리케이션. 이러한 작업은 일반적으로 Java에서 수행되지만 .NET에서 수행하는 경우 Java 및 많은 트랜잭션을 처리해야 하는 다른 서버 응용 프로그램에서 수행하는 것과 동일한 문제가 발생합니다. 예를 들어 수백만 명의 고객을 보유한 은행이나 금융 서비스 회사가 될 수 있습니다. 주소 변경, 자금 이체 등을 요청하며 밤에는 규정 준수 또는 기타 SLA 이유로 이 모든 작업을 처리해야 합니다. 따라서 더 많은 일괄 처리, 백엔드 처리가 있더라도 여전히 많은 정보를 처리할 수 있어야 하는 다른 서버 앱이 있고 그렇게 할 수 없는 경우에는 알다시피, 당신은 많은 어려움에 처해 있습니다.

확장성 문제

이러한 애플리케이션이 있는 경우 확장성이 필요할 가능성이 높습니다. 그럼 이제 이 문제가 어디에 있는지 이야기해 볼까요? 우리가 해결하려고 하는 확장성 문제는 어디에 있습니까? 확장성 문제는 실제로 애플리케이션 계층에 있지 않습니다. 제가 언급한 모든 애플리케이션은 일반적으로 더 많은 서버를 추가할 수 있고 전혀 문제가 없는 방식으로 설계되었습니다. 문제는 데이터 저장에 있습니다. 이것이 의미하는 바는 애플리케이션 데이터, 즉 관계형 데이터베이스가 있는 곳입니다. 이는 SQL 서버, Oracle, MySQL일 수 있습니다. 특정 판매업체가 아닙니다. 설계상 관계형 데이터베이스의 개념은 확장될 수 없습니다. 실제로 데이터 양 측면에서도 확장할 수 없습니다. 그렇기 때문에 NoSQL database은 매우 인기가 있지만 특히 트랜잭션 측면에서 그리고 메인프레임 레거시 데이터가 있는 경우에도 마찬가지입니다. 많은 애플리케이션이 레거시 데이터에 액세스해야 합니다. 따라서 병목 현상이 발생하는 곳이 바로 여기이며, 병목 현상이 있는 경우 이 계층의 확장 가능 여부는 중요하지 않으며 확장할 수 없습니다.

NoSQL databases는 확장성을 제공한다는 이유로 인기를 얻었습니다. 그리고 아시다시피 우리는 또한 NoSQL database 제품을 구매했지만 문제를 해결하지 못하는 경우가 많습니다. 기술적인 이유와 사업상의 이유로 사용할 수 없기 때문에 문제를 해결할 수 없습니다. 사용하려면 NoSQL database 관계형 데이터베이스가 아닌 데이터베이스에 데이터를 넣어야 합니다. 당신이 할 수 있는 일부 데이터. 확실히 넣을 수 있어요 NoSQL database 하지만 기존 비즈니스 데이터 중 상당수는 관계형 데이터베이스에 남아 있을 것입니다. 따라서 데이터를 다음으로 이동할 수 없는 경우 NoSQL database에, 그것들은 좋지 않아요. 따라서, 당신은 관계형 데이터베이스를 계속 사용하게 될 것이라는 점을 염두에 두고 이 문제를 해결해야 합니다. NoSQL database 혼합에서 이는 데이터의 하위 집합일 뿐입니다. 일반적으로 관계형 데이터베이스를 대체하는 것은 아닙니다. 그리고, NoSQL database 아시다시피, 솔직히 말해서 우리는 고객과 대화할 때 관계형 사용을 중단하라고 말하지 않습니다. 그런 일은 결코 일어나지 않을 것입니다. 우리는 그것을 관계형의 확장으로 사용한다고 말합니다. 따라서 관계형을 유지해야 한다면 문제를 해결해야 합니다. 혼합된 캐시가 바로 분산 캐시가 등장하는 부분입니다. 이것이 바로 우리가 이 대화를 나누는 이유입니다.

분산 캐시 배포(NCache)

분산 캐시를 조금 정의하겠습니다. 분산 캐시가 분산됩니다. 여기에서는 두 개 이상의 서버에 상주합니다. 논리적으로 말하면 별도의 캐싱 계층입니다. 물리적으로는 애플리케이션과 동일한 상자에 있을 수 있지만 논리적으로는 별도의 캐싱 계층입니다. 일반적으로 두 개 이상의 서버와 분산 캐시가 클러스터를 형성합니다. 따라서 이는 일반적으로 이러한 클러스터이며, TCP 기반 클러스터가 가장 일반적입니다. NCache 클러스터링에는 확실히 TCP를 사용합니다. 그리고 이 클러스터는 모든 리소스, 모든 서버, CPU, 메모리, 네트워크 카드가 모두 함께 풀링된다는 것을 의미합니다. 이것이 바로 이것이 확장 가능한 방법입니다. 용량을 늘려야 하면 서버를 더 추가할 수 있기 때문입니다.

분산 캐시 배포(NCache)

이곳에서도 할 수 있는 일입니다. 하지만 여기서는 할 수 없습니다. 제가 말했듯이 혼합에 다른 SQL 데이터베이스를 추가할 수 있지만, 아시다시피 이 데이터베이스가 있어야 합니다. 그림에 이 내용이 있으면 믹스에 이와 같은 것이 필요합니다.

분산 캐시는 저렴한 서버에 있습니다. 이는 고급 데이터베이스의 일반적인 웹 서버 유형 구성이 아닙니다. 대부분의 고객은 8코어 박스를 가지고 있는데 예전에는 듀얼 CPU였던 것 같습니다. 이제는 8코어라는 단어와 메모리가 많은 64비트라는 단어만 사용합니다. 많다는 것은 16~32GB가 우리가 보는 서버당 평균과 거의 비슷하다는 것을 의미합니다. 각 상자에 64GB를 초과하는 것도 권장하지 않습니다. 왜냐하면 64GB 이상의 메모리가 있는 경우 .NET에서는 가비지 수집이 필요하기 때문입니다. GC 자체는 시간이 많이 걸리는 작업이며 그 자체로 병목 현상이 발생하기 시작합니다. 따라서 최고급 서버를 몇 개 보유하는 것보다 더 많은 서버를 보유하는 것이 더 좋습니다. 왜냐하면 캐시가 의도적으로 분산되었음에도 불구하고 이제 병목 현상이 가비지 수집으로 변하기 시작하기 때문입니다. 그리고 우리는 수년에 걸쳐 많은 고통스러운 경험을 통해 이것을 배웠습니다. 아시다시피, 128GB까지 올라간 고객이 있었는데 갑자기 CPU에 많은 부담이 가해졌습니다. 그래서 처리 능력을 상당히 높여야 했고 데이터베이스처럼 보이기 시작했습니다. 그래서 우리는 그것을 낮추는 것이 좋습니다.

데이터베이스에 있는 데이터를 캐시합니다. 그리고 기본적으로 80%의 시간은 캐싱 계층으로 이동하고 20%의 시간은 데이터베이스로 이동합니다. 캐시는 인메모리 속도가 매우 빠르며 다음을 포함한 어떤 데이터베이스보다 훨씬 빠릅니다. NoSQL database, 우리보다 빠른 것을 포함하여 NoSQL database. NCache 적어도 어떤 데이터베이스보다 훨씬 빠릅니다. 아시다시피 데이터베이스는 디스크로 이동해야 하기 때문입니다. 그러나 모든 업데이트는 물론 실제 데이터베이스로 이동해야 합니다. 따라서 20%가 물론 일부 읽기도 포함됩니다.

이제 그렇게 하면 갑자기 데이터베이스에서 모든 압력이 사라집니다. 이제 실행됩니다. 읽기 속도가 훨씬 빨라지고 업데이트도 훨씬 빨라집니다. 따라서 확장성을 달성할 수 있을 뿐만 아니라 이제 애플리케이션이 확장 가능해질 뿐만 아니라 갑자기 빨라지는 것도 가능합니다. 그러나 캐시를 사용하는 주된 이유는 성능을 향상시키기 위한 것이 아닙니다. 이는 사람들이 전통적으로 캐시가 성능을 향상시키기 위해 존재한다고 생각했던 것과는 정반대입니다. 독립된 상황에서는 그렇습니다. 데이터베이스조차도 메모리 내 캐싱을 사용합니다. 우리의 NosDB 또한 내장된 캐싱을 사용하지만 실제로는 확장성을 위한 것입니다. 그렇게 할 수 있어야 하기 때문에 스스로 벗어날 수 없는 문제이기 때문입니다. 확장성을 얻기 위해 더 비싼 하드웨어를 구입할 수는 없습니다. 확장 가능한 애플리케이션을 가지려면 애플리케이션을 설계하고 올바른 인프라 또는 아키텍처의 일부로 올바른 구성 요소를 사용해야 합니다.

Java 측에서는 이를 인메모리 데이터 그리드라고 합니다. .NET 측에서는 이를 분산 캐시라고 합니다. 이에 대한 또 다른 단어는 인메모리(In-Memory)입니다. NoSQL 키값 저장소. 즉, 그것을 보는 세 가지 다른 방법이 있다는 뜻입니다. 이것은 NoSQL database 이것은 NoSQL 키 값 메모리 내 저장소. 왜냐하면 지속성이 없기 때문에 영구 저장소가 없기 때문입니다.

따라서 이와 같은 그림이 있으면 구조적으로 병목 현상이 전혀 발생하지 않는 응용 프로그램을 갖게 될 것이라고 확신하시기 바랍니다. 인프라처럼 이를 사용하도록 애플리케이션을 설계하는 경우. 더 깊이 들어가기 전에 질문이 있으신가요?

캐시가 오래되었는지, 아니면 케이스에서 뭔가를 업데이트했는지 어떻게 알 수 있나요? 그것에 대해 설명하겠습니다. 좋은 질문.

분산 캐시의 일반적인 사용

따라서 애플리케이션 아키텍처의 일부로 분산 캐시가 필요하다고 확신한다고 가정해 보겠습니다. 다음으로 떠오르는 질문은 이를 어떻게 사용합니까? 캐시를 어디에 사용하며, 각 사용 유형과 관련된 문제는 무엇입니까? 따라서 .NET 개발자로서 제 초점은 .NET이지만 다른 응용 프로그램에도 동일한 개념이 적용됩니다.

애플리케이션 데이터 캐싱

가장 일반적인 사용 사례는 애플리케이션 데이터 캐싱입니다. 지금까지 제가 이야기한 내용은 데이터베이스가 있고 여기에 데이터를 캐시하기만 하면 됩니다. 따라서 목표는 데이터베이스에 자주 접근하지 않는 것입니다. 그리고 제가 말한 모든 혜택을 누리실 수 있습니다. 그렇게하자마자 문제가 발생하는데 방금 말씀하신 것이 바로 그것입니다. 이제 데이터는 두 곳에 존재합니다. 하나는 항상 필요한 데이터베이스인 영구 마스터 저장소이고 두 번째는 캐시입니다. 그리고 실제로 캐시 내에는 여러 곳에 존재하며 이에 대해서도 이야기하겠습니다.

그렇다면 데이터가 여러 곳에 존재한다면 무엇이 잘못될 수 있을까요? 아시다시피 동기화가 중단될 수 있습니다. 따라서 분산 캐시가 해당 상황을 처리할 수 없는 경우 읽기 전용 데이터를 캐시해야 합니다. 실제로 대부분의 사람들은 캐시에 대해 생각할 때 무릎 떨림 반응은 읽기 전용 데이터에만 해당됩니다. 왜냐하면 변경되는 데이터를 캐시하면 이를 트랜잭션 데이터라고 부르기 때문입니다. 그러면 동기화가 되지 않게 됩니다. 그리고 동일한 은행 계좌에서 백만 달러를 두 번 인출하는 고전적인 문제가 여기에 있다는 것을 알고 계시나요? 따라서 캐시가 이 문제를 해결하지 못하면 매우 작은 하위 집합으로 제한됩니다. 캐시할 수 있는 데이터의 전부는 약 10~15%이며 이는 충분하지 않습니다. 따라서 좋은 분산 캐시는 이 문제를 해결해야 하며 이에 대해 이야기하겠습니다.

ASP.NET 특정 캐싱

두 번째 사용 사례는 ASP.NET 응용 프로그램이 있는 경우 여기에 저장할 수 있는 세 가지 항목이 있다는 것입니다. 물론 새로운 프레임워크가 등장하면서 이러한 상황도 바뀌고 있습니다. 따라서 가장 일반적인 것은 ASP.NET 세션 상태입니다. 이는 ASP와 ASP 모두에 존재합니다..NET core 그리고 전통적인 ASP 프레임워크입니다. 세션은 기본적으로 In-Proc을 저장하거나 SQL 서버에 저장하는 것입니다. 둘 다 확장성 문제가 있습니다. SQL에도 성능 문제가 있습니다. 그리고 관계형 데이터베이스는 Blob을 저장하도록 설계되지 않았기 때문에 세션은 Blob으로 저장됩니다. 두 번째로, 애플리케이션 데이터를 캐시하고 데이터베이스로 이동하지 않으려는 것과 같은 이유로 데이터베이스에 세션을 유지하고 싶지 않습니다. 따라서 이는 ASP.NET 응용 프로그램에 대한 매우 이상적인 사용 사례입니다. 그리고 아시다시피 이것이 대부분의 고객이 가장 먼저 사용하는 것입니다. 기존 애플리케이션이 있고 분산 캐시를 통합하려는 경우 이를 통합하는 데 필요한 최소한의 노력은 세션입니다. 왜냐하면 ASP는.NET framework 타사 캐시를 연결할 수 있습니다. 프로그래밍이 필요하지 않습니다. web.config를 변경하면 됩니다. 사실, 빨리 보여드리겠습니다. 그냥 앞뒤로 점프하겠습니다.

예를 들어, 저는 작은 ASP.NET 애플리케이션과 여기에 web.config를 가지고 있습니다. 물론 다음을 사용하겠습니다. NCache 예를 들어 보겠습니다. NCache 세션 상태 공급자로서 이 어셈블리를 배치해야 합니다. 따라서 "어셈블리 추가" 태그를 지정합니다. 그래서 이번 집회는 NCache ASP.NET 세션 상태 공급자 인터페이스를 구현했습니다.

<?xml version="1.0" encoding="utf-8"?>
<configuration>
    <system.web>
        <machineKey validationKey="A01D6E0D1A5D2A22E0854CA612FE5C5EC4AECF24" decryptionKey="ACD8EBF87C4C8937" validation="SHA1" />
        <compilation defaultLanguage="c#" debug="true" targetFramework="4.0">
            <compilers>
                <compiler language="c#" type="Microsoft.CSharp.CSharpCodeProvider, System, Version=2.0.0.0, Culture=neutral, PublicKeyToken=B77A5C561934E089" extension=".cs" compilerOptions="/d:DEBUG;TRACE" />
            </compilers>
            <assemblies>
                <add assembly="Alachisoft.NCache.SessionStoreProvider, Version=4.6.0.0, Culture=neutral, PublicKeyToken=CFF5926ED6A53769" />
            </assemblies>
        </compilation>
        
        <customErrors mode="RemoteOnly" />
        <authentication mode="None" />
        <authorization>
            <allow users="*" />
        </authorization>
        <trace enabled="false" requestLimit="10" pageOutput="false" traceMode="SortByTime" localOnly="true" />
        <!-- For NCache Developer Edition replace 'myPartitionedCache' with 'myCache' or any other local-cache-->
        <sessionState cookieless="false" regenerateExpiredSessionId="true" mode="Custom" customProvider="NCacheSessionProvider" timeout="1">
            <providers>
                <add name="NCacheSessionProvider" type="Alachisoft.NCache.Web.SessionState.NSessionStoreProvider" exceptionsEnabled="true" enableSessionLocking="true" emptySessionWhenLocked="false" sessionLockingRetry="-1" sessionAppId="NCacheTest" useInProc="false" enableLogs="false" cacheName="myPartitionedCache" writeExceptionsToEventLog="false" AsyncSession="false" />
            </providers>
        </sessionState>
        <!--  GLOBALIZATION
        This section sets the globalization settings of the application. 
		-->
        <globalization requestEncoding="utf-8" responseEncoding="utf-8" />
        <xhtmlConformance mode="Legacy" />
        <pages controlRenderingCompatibilityVersion="3.5" clientIDMode="AutoID" />
    </system.web>
    <system.webServer>
        <directoryBrowse enabled="true" showFlags="Date, Time, Size, Extension, LongDate" />
    </system.webServer>
</configuration>

이것이 바로 ASP를 준수하는 방식입니다..NET framework 사양은 타사 캐시입니다. 따라서 이것이 가장 먼저 해야 할 일이고 두 번째로 이름 공간을 변경하는 것입니다. 실제로는 이 태그를 사용하면 됩니다. 따라서 모드가 사용자 정의이고 제한 시간이 20분이 아닌지 확인하십시오. 그것은 XNUMX이어야 합니다. 그리고 나는 이것으로 다시 돌아올 것입니다. 캐시 이름입니다.

의 경우 NCache, 모든 캐시의 이름이 지정됩니다. 나는 이것에 대해 다시 돌아올 것이다. 이것이 바로 여러분이 하는 일의 전부이며 애플리케이션은 세션을 캐시에 저장하기 시작합니다. 그리고 SQL보다 훨씬 빠른 인메모리이기 때문에 즉시 성능 향상을 확인할 수 있습니다. In-Proc보다 빠르지는 않지만 SQL보다 빠르지만 두 경우 모두 확장성이 뛰어납니다.

ASP.NET의 두 번째 사용 사례는 보기 상태입니다. MVC 프레임워크를 사용하지 않는 경우, 레거시 ASP.NET에 있는 경우 보기 상태가 있을 수도 있고 모를 수도 있습니다. 보기 상태는 모르시는 분들을 위해 설명하자면, 게시글이 있을 때만 돌아오기 위해 웹 서버에서 브라우저로 보내는 암호화된 문자열입니다. 따라서 크기가 수백 킬로바이트에 이를 수 있습니다. 여기에 애플리케이션이 처리해야 하는 수백만 개의 요청을 곱하면 두 가지 나쁜 일이 발생합니다. 하나는 많은 대역폭을 소비하고 대역폭은 무료가 아닙니다. 애플리케이션을 호스팅하면 대역폭 비용을 지불해야 합니다. 둘째, 페이로드가 훨씬 무거워서 응답 시간이 느려집니다. 따라서 서버 측에서 이를 캐시할 수 있다면 모든 것을 제거하고 애플리케이션을 더 빠르게 만들 수 있습니다.

출력 캐시는 ASP입니다..NET framework 페이지 출력을 캐시할 수 있으므로 페이지 출력이 변경되지 않으면 마지막 실행에서 가져옵니다. 따라서 각 웹 서버에 해당 출력 캐시의 별도 복사본을 보관하는 것보다 웹 팜에 분산 캐시를 연결하는 것이 더 좋습니다. 실제로 원하는 것은 애플리케이션 관리 관점에서 이러한 웹 서버를 완전히 무상태로 만드는 것입니다. 상태 비저장인 경우 모든 패치를 수행할 수 있으며, 모든 버그 수정, 애플리케이션 업그레이드는 소프트웨어 업그레이드 측면에서 캐시 업그레이드보다 훨씬 더 자주 수행됩니다. 따라서 여기서 유지되는 상태가 없다면 웹 팜에서 해당 상자 중 하나를 삭제해도 사용자는 눈치 채지 못할 것입니다. 모든 상태는 여기나 데이터베이스에 유지되고 있으며 자주 만지는 항목이 아니므로 다시 캐시하세요.

이제 ASP.NET 특정 캐싱의 경우 프로그래밍이 필요하지 않다는 한 가지 좋은 점이 있습니다. 따라서 별도의 노력 없이 즉시 연결하기만 하면 됩니다. 물론 당신이 하는 유일한 일은 온전한 테스트입니다. 예를 들어 ASP.NET 세션 상태를 연결하고 In-Proc 세션을 사용하는 경우 일부 개체가 직렬화 가능하지 않다는 것을 발견할 수 있습니다. 그리고 당신은 몰랐고 갑자기 응용 프로그램에서 예외가 발생하기 시작합니다. 즉, 수행해야 할 수준의 테스트를 의미합니다. 그러나 이제 또 다른 특이한 문제가 있습니다. 데이터 복사본이 두 개 있는 것과 달리 이제 데이터는 캐시에만 존재합니다.

그렇다면 메모리 내 저장소가 마스터 저장소인 경우 무엇이 잘못될 수 있습니까? 기계가 다운됩니다. 예, 아시다시피 서버가 다운되면 데이터가 손실되며 이 데이터, 특히 세션이 손실되는 것을 원하지 않습니다. 따라서 좋은 분산 캐시는 이 문제를 해결해야 하며 일반적으로 동일한 데이터가 적어도 두 위치에 존재하는 복제를 통해 수행됩니다. 그렇지 않은 경우 해당 캐시에 세션을 넣지 않는 한, 실제로는 그렇지 않습니다. 사용자가 이 세션을 사용하는지 여부는 중요하지 않습니다. 대부분의 상황에서는 그렇지 않습니다.

런타임 데이터 공유

세 번째 활용 사례는 런타임 데이터 공유 이벤트를 통해. 이는 일반적으로 사람들이 메시지 대기열을 사용하여 수행한 작업입니다. 아시다시피 고유한 위치가 있고 분산 캐시가 이를 대체할 수는 없지만 분산 캐시는 훨씬 더 빠르고 확장성이 뛰어나며 메시지 또는 데이터 공유가 있는 경우 동일한 위치, 동일한 데이터 센터에서 수행되면 분산 캐시를 사용할 수 있습니다. Pub / Sub 뭐, 그렇게 하면 돼. 특정 항목에 대한 관심을 표시할 수 있는 다른 유형의 이벤트도 있습니다. 이 항목이 변경되면 알려주세요. 아니면 다음과 같은 경우에는 NCache 라는 기능이 있습니다 연속 쿼리 SQL 문을 작성하고 다음과 같이 말할 수도 있습니다.CUSTOMER.CITY = NEW YORK인 고객을 선택하세요.'. 이 데이터 세트가 업데이트, 삭제되거나 새 개체가 추가, 업데이트 또는 삭제되면 알려주시기 바랍니다. 따라서 애플리케이션이 수행할 수 있는 모니터링 유형이 있다면 소비자는 알림을 받고 싶은 내용에 대해 훨씬 더 똑똑해질 수 있습니다. 그리고 생산자는 캐시를 계속 업데이트할 수 있습니다.

이것이 많은 사람들이 모르는 세 번째 사용 사례입니다. 그러나 이제는 캐시가 이를 수행하기에 매우 좋은 장소라는 것이 점점 더 분명해지고 있습니다. 왜냐하면 여러분은 이미 이 두 가지 이유로 캐시를 사용하고 있기 때문입니다. 따라서 이것을 입력하면 응용 프로그램에 통합하는 것이 매우 간단합니다. 자세한 내용을 살펴보기 전에 질문이 있으신가요?

Rescale과 함께 비즈니스를 가속화하는 방법에 대해 알아보세요.

그래서 먼저 캐시가 어떻게 생겼는지 보여드리겠습니다. 그러면 우리는 그것을 우리가 말하는 모든 맥락에 ​​적용할 수 있습니다. 나는 사용할 것이다 NCache 예로서. 그래서 Azure에는 여러 개의 VM이 있습니다. 그래서 저는 데모1, 데모2, 데모 클라이언트를 갖게 되었습니다. Demo1과 Demo2는 내 캐시 서버 VM입니다. 데모 클라이언트는 응용 프로그램 서버 상자입니다. 이것이 바로 캐시 클라이언트입니다. 그래서 나는 그 모든 것을 가지고 있습니다.

Azure VM

저는 가서 로그인했습니다. 예를 들어 데모 클라이언트에 로그인했다고 가정해 보겠습니다. 캐시를 만들어 보겠습니다. 그래서 나는 사용할 것이다. NCache 매니저, 그래픽 도구입니다. 계속해서 '새 클러스터 캐시 생성'이라고 말씀드리겠습니다.

캐시 생성

의 경우 NCache, 모든 캐시의 이름이 지정됩니다. 나는 모든 세부 사항을 설명하지 않을 것입니다. 각 캐시에 이름을 지정하겠습니다.

캐시 이름 지정

캐시의 토폴로지를 선택하겠습니다. 토폴로지 실제로는 저장 및 복제 전략입니다. 따라서 토폴로지는 다음과 같은 경우에 사용됩니다. NCache, 파티션 복제본이라는 토폴로지가 있다고 가정해 보겠습니다. 따라서 이 두 서버는 여기서 캐시 서버이고 각 서버에는 하나의 파티션이 있습니다. 그렇다면 다음과 같은 경우를 가정해보자 NCache, NCache 각 서버에 대해 하나의 파티션을 생성하고 각 서버에는 다른 서버 파티션의 복제본이 포함됩니다. 각 파티션에는 총 버킷 수의 n분의 XNUMX이 포함됩니다. 다음의 경우 NCache 캐시당 1000개의 버킷이 있습니다.

캐싱 토폴로지

따라서 500노드 클러스터인 경우 각각 XNUMX개의 버킷이고, XNUMX노드 클러스터인 경우 XNUMX/XNUMX, XNUMX/XNUMX, XNUMX/XNUMX이 됩니다.

파티션 복제본, 파티션은 활성 상태이고 복제본은 활성 상태가 아니며 수동적입니다. 따라서 클라이언트는 파티션과만 통신하며 클라이언트가 여기에서 항목을 업데이트하면 파티션이 계속해서 이를 복제본에 복제하고 해당 복제는 기본적으로 비동기식이라고 가정해 보겠습니다. 진정한 확장성을 얻으려면 이 최종 일관성 모델을 사용해야 하기 때문입니다. 그러나 어떤 경우에는 귀하의 데이터가 매우 민감합니다. 아시다시피, 은행과 같은 금융 서비스 회사가 많이 있습니다. NCache 그들의 데이터는 실제로 돈입니다. 따라서 이 경우 최종 일관성을 수행할 수 없습니다. 따라서 동기 복제를 수행해야 합니다. 즉, 두 위치 모두에서 데이터가 업데이트될 때까지 애플리케이션이 대기한다는 의미입니다. 서버가 다운되는 경우, 예를 들어 3개 노드 클러스터가 있고 서버 3이 다운되고 파티션 3이 다운되면 복제본 XNUMX이 즉시 활성화됩니다.

서버 추가 시 데이터 밸런싱

따라서 이것이 고가용성을 얻는 방법이며 이제 일단 활성화되면 이제 서버가 1개만 있고 파티션은 2개만 있다는 것을 깨닫게 될 것입니다. 이는 그래야 하는 방식이 아닙니다. 따라서 파티션 2 및 XNUMX와 자체적으로 병합되며, 완료되면 여기에 파티션 XNUMX의 복제본이 생성됩니다.

그런 경우에는 모두 NCache 애플리케이션이 그런 일이 일어나고 있다는 사실조차 깨닫지 못한 채 런타임에 수행됩니다. 마찬가지로 2노드 클러스터가 있고 세 번째 서버를 추가하면 전체 맵이 여기에서 여기로 자동으로 변경됩니다. 그래서 그 선택이 의미하는 바는 바로 이것이었습니다.

그럼 그냥 골라볼까 파티션 복제본 토폴로지로.

복제 전략

비동기 복제를 유지하겠습니다.

복제 전략

첫 번째 서버인 데모 1을 선택하고 두 번째 서버인 데모 2를 선택하겠습니다.

클러스터된 캐시 구성원 노드 선택

모든 기본값을 사용하겠습니다. 지정하겠습니다. 단 1Gig이고 파티션 크기를 지정하겠습니다.

저장소 크기 지정

귀하의 경우 16Gig 시스템이 있는 경우 OS 및 기타 프로세스를 위해 약 2~2.5Gig를 남겨두고 캐시 및 남은 메모리를 위해 나머지 모든 것을 소비해야 합니다. 그 중 절반은 활성 파티션이어야 하고 나머지 절반은 활성 파티션이어야 합니다. 그 중 복제품을 위한 것입니다.

용량 계획을 세울 때 세션의 경우 세션에 유지하기에 충분한 메모리가 있도록 충분한 메모리를 할당하는 것이 매우 중요합니다. 그렇지 않고 캐시가 이 메모리를 모두 사용하면 캐시가 가득 찬 것으로 간주됩니다. 그러면 캐시가 새 항목을 거부하거나 기존 항목 중 일부를 제거하는 두 가지 중 하나만 발생합니다. NCache 세 가지 알고리즘을 제공합니다. 가장 일반적인 것은 가장 최근에 사용되지 않은 것입니다.

퇴거 정책 지정

그래서, NCache 캐시가 가득 찬 것으로 간주되면 즉시 캐시의 5%를 제거합니다. 이제 이것을 만들었으므로 클라이언트 노드를 추가하겠습니다. 이 경우에는 데모 클라이언트이고 캐시를 시작하겠습니다.

클라이언트 노드 추가

따라서 캐시를 시작하면 뒤에서 많은 일이 일어나고 있습니다. 새로운 클러스터가 형성되고 있습니다. 클라이언트에 전파되는 클러스터 멤버십이 형성되고 있습니다. 그렇다면 클라이언트는 클러스터 멤버십이 무엇인지 알고 있습니까? 분포도는 무엇입니까? 따라서 모든 작업이 완료되면 모든 것이 완료된 것입니다. 이제 통계를 말하겠습니다. PerfMon을 좀 보고 싶어요. 그리고 빠르게 실행되는 스트레스 테스트 도구라는 이 도구를 빠르게 실행하고 싶습니다. 사용자 환경에서 캐시를 신속하게 테스트합니다.

스트레스 테스트 도구 실행

따라서 이를 수행하기 위해 프로그래밍을 할 필요가 없습니다. 캐시는 이렇게 생겼습니다. 이런 식으로 설치하게 됩니다. 설치한다고 해보자 NCache. 응용 프로그램 서버가 구성된 2노드 클러스터를 가져오는 데 이 정도의 시간만 걸립니다. 귀하의 경우에는 물론 둘 이상의 클라이언트가 있습니다. 가장 일반적인 구성은 약 5~8개의 클라이언트와 2~3개의 노드 캐시 클러스터입니다. 그리고 더 많은 클라이언트를 추가하면 더 많은 서버가 추가됩니다.

캐시 통계

이제 이 캐시가 실행되었으므로 실제 주제로 돌아가겠습니다. 이제 우리가 수행하는 모든 작업에서는 이 명명된 캐시를 어떻게 생성했는지 염두에 두어야 합니다. 그리고 ASP.NET 특정 세션 상태를 이미 보여 드렸습니다.

애플리케이션 데이터 캐싱 개요(API)

이제 오늘 제 강연의 핵심인 애플리케이션 데이터 캐싱에 대해 살펴보겠습니다. 따라서 애플리케이션 데이터 캐싱의 경우 프로그래밍해야 하는 API가 있습니다. 왜냐하면 ASP는.NET core 이제 해당 API를 호출할 수 있는 IDistributed Cache라는 인터페이스가 있으며 뒤에서 타사 캐시를 플러그인할 수 있습니다. Java 측에는 JCache라는 매우 강력한 표준 API가 있지만 .NET 측에는 아무것도 없습니다. 따라서 대부분의 경우 실제로 실제 캐시 API 자체를 프로그래밍해야 합니다. 그러나 API는 매우 간단합니다.

  • 캐시 연결
    ICache cache = CacheManager.GetCache("myCache");
    cache.Dispose();
  • 데이터를 가져 오는 중
    Employee employee = cache.Get<Employee>("Employee:1000"); 
    bool isPresent = cache.Contains("Employee:1000");
  • 데이터 쓰기
    cache.Add("Employee:1000", employee);
    cache.AddAsync("Employee:1000", employee);
    
    cache.Insert("Employee:1000", employee);
    cache.InsertAsync("Employee:1000", employee);
    
    Employee employee = (Employee) cache.Remove("Employee:1000");
    cache.RemoveAsync("Employee:1000");

의 경우 NCache 알고 보면 이는 ASP.NET 캐시 개체와 매우 유사해 보입니다. 따라서 기본적으로 수행하는 작업은 캐시를 수행하는 것입니다. 가져오기, 개체 가져오기, 캐시 도트 추가, 삽입, 제거 또는 비동기 버전도 있습니다. 비동기는 캐시가 업데이트될 때까지 기다리지 않고 컨트롤을 반환하고 이 경우 콜백을 지정할 수 있음을 의미합니다.

애플리케이션이 어떤 모습인지 빠르게 보여드리겠습니다. 그래서 저는 다음을 사용하는 아주 간단한 콘솔 애플리케이션을 갖게 되었습니다. NCache.

using System;
using Alachisoft.NCache.Runtime;
using Alachisoft.NCache.Web.Caching;
using Alachisoft.NCache.sample.data;

namespace BasicOperations
{
    public class BasicOperations
    {
        public static void Main(string[] args)
        {
            try
            {
            //Initialize cache via 'initializeCache' using 'Cache Name'
            //to be initialized. 
            Cache cache = NCache.InitializeCache("demoCache");
            cache.Clear();

            //Another method to add item(s) to cache is via CacheItem  object
            Customer customer = new Customer();
            customer.Name = "David Johnes";
            customer.Age = 23;
            customer.Gender = "Male";
            customer.ContactNo = "12345-6789";
            customer.Address = "Silicon Valley, Santa Clara, California";

            DateTime calendar = new DateTime();
            calendar.AddMinutes(1);

            //Adding item with an absolute expiration of 1 minute
            cache.Add("Customer:DavidJohnes", customer, calendar, Cache.NoSlidingExpiration, CacheItemPriority.Normal);
            Customer cachedCustomer = (Customer) cache.Get("Customer:DavidJohnes");
            ...

따라서 가장 먼저 해야 할 일은 다음과 같은 경우에 캐시 어셈블리를 참조하는지 확인하는 것입니다. NCache 두 개입니다. 있다 NCache.실행 시간, NCache.편물 그런 다음 다시 두 개의 이름 공간을 사용해야 합니다. NCache. NCache.실행 시간, NCache.웹.캐싱. 그런 다음 애플리케이션 시작 부분(콘솔의 경우)이 바로 거기에 있습니다. ASP.NET 애플리케이션의 경우 이는 아마도 global.asax일 것입니다. 캐시에 연결해야 하며 캐시 이름이 무엇이든 캐시 이름이 입력되는 곳입니다. 그것이 여기에 들어오는 것입니다. 이제 캐시 핸들이 있으므로 애플리케이션을 계속 진행할 수 있고 객체를 생성할 수 있으며 다음 작업을 수행할 수 있습니다. 캐시.추가. 문자열 기반 키를 지정하고 키는 고유해야 합니다. 그런데 이것은 좋은 열쇠가 아닙니다. 키는 훨씬 더 구체적이어야 하며 여기에 개체가 있습니다. 그리고 내 말은, 이것이 바로 나중에 여러분이 할 수 있는 방법이라는 것입니다. 캐시.가져오기 캐시에서 개체를 가져올 수 있습니다.

이제 귀하가 수행한 이 호출은 실제로 다음과 같은 결과를 가져왔습니다. NCache, 그래서 당신이 그랬을 때 캐시.추가, 기본적으로 여기에서 데이터가 들어가야 할 파티션으로 이동했습니다. 그래서 캐시를 수행했습니다. 거기에 추가하면 이 파티션이 해당 데이터를 복제본에 복제했습니다. 그것이 비동기식 애플리케이션이라면 이 파티션만 업데이트되고 제어권이 다시 돌아왔습니다. 비동기 호출을 한 경우에는 이 파티션도 마찬가지이며 심지어 파티션이 업데이트될 때까지 기다리지도 않았습니다. 그런데 딱 그거 하나 캐시.추가 호출로 인해 이 모든 작업이 완료되었습니다.

캐싱 토폴로지

그리고 마찬가지로 캐시.가져오기 클라이언트는 데이터가 있는 곳으로 직접 이동합니다. 따라서 아래의 분포 맵을 사용하여 데이터가 어디에 있는지 파악하고 직접 어디로 가서 가져옵니다. 예를 들어, 항목 번호 3을 원한다면 거기에서 바로 가져오면 됩니다.

따라서 이 코드는 배후에 있으며 실제로 일어나는 일입니다. 데이터베이스로. 당신은 무엇입니까? 바로 캐시입니다. 사실 그 얘기도 조금 있다가 할게요. 그렇다면 데이터를 자동으로 직렬화/역직렬화하나요? 예, 사실 그 이상입니다. 따라서 여기에서 여기로 데이터를 보내기 전에 개체를 직렬화해야 합니다. 다음의 경우 NCache, NCache 캐시에 직렬화된 형식으로 보관합니다. 그리고 캐시를 수행하면 캐시가 다시 돌아온 다음 클라이언트 자체에서 역직렬화됩니다. 그리고 여러분이 그것을 얻을 때쯤에는 모두 역직렬화되어 있을 것입니다. 따라서 API는 매우 간단해 보이지만 수행해야 할 작업이 많습니다.

앱 데이터 캐싱 기능

자, 애플리케이션 데이터 캐싱에 관해 가장 큰 고민은 데이터가 두 곳에 존재한다는 점이었지요. 그리고 캐시가 이러한 문제를 해결하지 못한다면 그 이점은 실제로 제한될 것입니다. 그렇다면 캐시는 이러한 문제를 어떻게 해결합니까?

절대 만료

XNUMX위라고 합니다 만료 그리고 거기에는 절대 만료 이는 이 개체가 만료된다는 의미입니다. 지금으로부터 10분 후에 가정해 보겠습니다. 따라서 해당 개체를 캐시에 얼마나 오래 보관하는 것이 안전한지 모든 개체에 대해 학습된 추측으로 만듭니다. 그리고 해당 시간이 끝나면 캐시는 해당 개체를 자동으로 제거합니다.

코드에서 어떻게 보이는지 보여드리겠습니다. 따라서 다음의 경우에는 NCache 동일한 캐시.Add 호출을 보면 세 번째 인수는 지금으로부터 XNUMX분 값을 갖는 날짜 시간 인수입니다.

public static void Main(string[] args)
{
    try
    {
        //Initialize cache via 'initializeCache' using 'Cache Name'
        //to be initialized. 
        Cache cache = NCache.InitializeCache("demoCache");
        cache.Clear();

        //Another method to add item(s) to cache is via CacheItem  object
        Customer customer = new Customer();
        customer.Name = "David Johnes";
        customer.Age = 23;
        customer.Gender = "Male";
        customer.ContactNo = "12345-6789";
        customer.Address = "Silicon Valley, Santa Clara, California";

        DateTime calendar = new DateTime();
        calendar.AddMinutes(1);

        //Adding item with an absolute expiration of 1 minute
        cache.Add("Customer:DavidJohnes", customer, calendar, Cache.NoSlidingExpiration, CacheItemPriority.Normal);
        Customer cachedCustomer = (Customer) cache.Get("Customer:DavidJohnes");
        ...

따라서 이는 기본적으로 캐시가 지금부터 XNUMX분 후에 이 개체를 만료한다는 의미입니다. XNUMX분 후에 해당 개체가 캐시에서 제거되므로 필요한지 여부는 중요하지 않습니다. 왜? XNUMX분 이상 캐시에 보관하는 것이 불편하기 때문입니다. 그리고 왜 기분이 좋지 않습니까? 왜냐하면 데이터베이스에서 변경될 것이라고 생각하기 때문입니다. 캐시에 보관하는 것은 안전하지 않습니다.

슬라이딩 만료

또 다른 유형의 만료가 있습니다. 슬라이딩 만료, 이는 완전히 다른 목적으로 사용됩니다. 캐시를 최신 상태로 유지하기 위한 것이 아니라 정리를 위한 것입니다. 예를 들어 세션의 경우 NCache 기본적으로 간격을 지정하고 10분, 20분, 5분이라고 말하는 슬라이딩 만료를 사용합니다. 그러니 오랫동안 아무도 그 물건에 손을 대지 않는다면 NCache 캐시에서 해당 항목을 제거합니다.

따라서 슬라이딩 만료는 이름이 여전히 만료이지만 완전히 다른 용도로 사용됩니다. 캐시를 최신 상태로 유지하기 위해 애플리케이션 데이터 캐싱에 필요한 절대 만료입니다. 거의 모든 캐시에는 절대 만료일이 있습니다. 포함 Redis, 모두가 그것을 가지고 있습니다.

데이터베이스와 캐시 동기화

그러나 절대 만료의 문제는 추측만 한다는 것입니다. 그 추측이 틀렸고 데이터베이스의 데이터가 실제로 변경되면 어떻게 될까요? 그러면 어떻게 되나요? 우리는 메커니즘을 생각해내야 합니다. 그러니까, 당신이 할 수 있는 능력이 있다면 캐시를 데이터베이스와 동기화 여기서는 매우 특정한 데이터 세트에 대한 변경 사항을 데이터베이스에서 모니터링하도록 캐시에 지시할 수 있습니다.

NCache예를 들어, 이 ADO.NET SQL 캐시 종속성 기능을 사용합니다. 어디서, 지정하면 이 기능을 사용한다면 어떻게 사용되는지 보여드리겠습니다. 이 기능을 사용한다면 NCache 데이터베이스를 모니터링하고 데이터베이스에 이를 알리도록 요청합니다. NCache 그 데이터가 변경되면. 예를 들어 SQL 종속성 예제가 있다고 가정해 보겠습니다. 그래서 다시 동일한 캐시를 수행하고 있습니다. 여기에 추가하세요. 그래서 저는 동일한 캐시를 수행하고 있습니다.추가합니다. 나한테 열쇠가 있어. 이제 개체를 갖는 대신 실제 개체와 몇 가지 다른 항목을 포함하는 구조인 캐시 항목이 있습니다. 예를 들어 제품 테이블의 단일 행에 대한 SQL 문이 포함되어 있습니다. Northwind 데이터베이스에 제품을 캐싱하고 있으므로 이 SQL 문은 NCache 그런 다음 사용하십시오.

private static void AddProductToCacheWithDependency(Product product)
    {
        // Any change to the resultset of the query will cause cache to invalidate the dependent data
        string queryText = String.Format("SELECT ProductID, ProductName, QuantityPerUnit, UnitPrice FROM dbo.PRODUCTS WHERE PRODUCTID = {0}", product.Id);

        // Let's create SQL depdenency
        CacheDependency sqlServerDependency = new SqlCacheDependency(_connectionString, queryText);

        CacheItem cacheItem = new CacheItem(product);
        cacheItem.Dependency = sqlServerDependency;

        // Inserting Loaded product into cache with key: [item:1]
        string cacheKey = GenerateCacheKey(product);
        _cache.Add(cacheKey, cacheItem);
    }

그래서 SQLCacheDependency 수업 NCache 이는 우리 고유의 클래스이지만 뒤에서는 ADO.NET SQL 캐시 종속성에 매핑됩니다. 이제 실제로 이 전화를 걸고 있으므로 전화를 걸려면 여기로 전화해야 합니다. 그리고 해당 호출은 캐시 서버로 전달되며 이제 캐시 서버는 SQL 서버 데이터베이스에 대해 ADO.NET 호출을 수행합니다. 그리고 이제 캐시 서버가 데이터베이스의 클라이언트가 됩니다. 그리고 데이터베이스에 이 데이터 세트가 변경되면 알려주시기 바랍니다.

분산 캐시 배포(NCache)

그리고 SQL Server에는 Oracle과 같은 데이터베이스 알림 메커니즘이 있습니다. 적어도 이 두 데이터베이스에 대해서는 이 기능을 사용할 수 있습니다. 그리고 SQL 캐시 종속성을 사용하면 추측할 수 없는 경우에도 데이터가 데이터베이스와 일관성을 유지할 것이라는 확신을 가질 수 있습니다.

이에 대해 질문이 있으신가요? 따라서 프레임워크 구성 요소가 있습니다. 그래서, NCache EF, EF6 및 이제 EF Core(EF Core까지)용 플러그인도 있습니다. EF Core 이전에는 EF에 실제로 플러그형 아키텍처가 없었습니다. 따라서 우리는 사용자 정의 ADO.NET 공급자를 구현하고 SQL 쿼리를 캐시해야 했습니다.

SQL Core는 훨씬 더 유연한 아키텍처입니다. 이제 L2 캐시를 제공할 수 있게 되었습니다. NHibernate는 오랫동안 존재해온 것입니다. NHibernate는 매우 오랫동안 그러한 아키텍처를 가지고 있었습니다. NCache NHibernate 및 Java 클라이언트용 Hibernate용 L2 캐시를 제공했습니다. 그러나 이제 EF Core에는 해당 아키텍처가 있습니다. 따라서 EF Core의 이점은 이러한 호출을 할 필요가 없다는 것입니다. 물론 단점은 기능 측면에서 사용하는 캐시의 하위 집합이 매우 작다는 것입니다. 예를 들어 SQL 종속성 부분과 같은 다른 모든 것들은 NCache 제공하고 구성 파일을 통해 구성할 수 있지만 플러그형 아키텍처를 사용하는 경우 최소 공통 분모 접근 방식을 거쳐야 하는 사용해야 하는 다른 많은 기능도 제공합니다. 따라서 API는 무엇을 사용하든 정교한 기능을 많이 사용할 수 없지만 이제는 모든 캐시가 이를 제공합니다. 따라서 그들은 모든 사람을 위해 유연해야 합니다. 반면, 예를 들어 Java 측면에서 이점을 얻으려면 거의 모든 캐시에 내가 말하는 이러한 기능이 모두 포함되어 있습니다. .NET 측면에서는 다음 외에는 거의 아무것도 없습니다. NCache. 그러니까 그건 진짜 아닌데 NCache문제는 .NET이 이러한 모범 사례를 사용하는 Java 커뮤니티만큼 발전되거나 성숙하지 않다는 사실입니다. 그래서 점점 더 많아지고 있습니다. 지금이라는 사실은 .NET Core 이렇게 큰 변화를 겪었다는 것은 상황이 어떻게 개선될 것인지를 보여주는 아주 좋은 지표입니다.

그러나 현재로서는 캐시를 데이터베이스 만료와 동기화된 상태로 유지하는 것만으로는 충분하지 않습니다. 만료일을 넘어야합니다. 캐시를 데이터베이스와 동기화해야 합니다. 그리고 데이터베이스가 알림을 지원하지 않는 경우 폴링 접근 방식을 사용할 수 있습니다. NCache 구현했습니다.

CLR 저장 프로시저를 사용하여 데이터베이스의 데이터를 캐시에 직접 추가할 수 있는 세 번째 접근 방식이 있습니다. 따라서 전체 패러다임을 뒤집는 것과 같습니다. 이제 데이터베이스가 캐시를 공급하고 있습니다. 예를 들어, 당신은... 속도를 높일 수 있는 트리거를 가지고 있습니다. 그렇지 않으면 모든 주제를 완료할 수 없습니다. 따라서 이는 실제로 이점을 얻을 수 없는 매우 중요한 기능이며 비관계형 데이터 소스에 대해서도 캐시를 동기화할 수 있습니다. 예를 들어 다음과 같은 경우 NCache 호출할 수 있는 코드인 사용자 정의 종속성 기능이 있습니다. 데이터 원본이 클라우드이고 실제로 데이터가 무엇인지 알기 위해 매번 호출되는 웹 메서드라고 가정해 보겠습니다. 그렇다면 그 어느 것도 작동하지 않으며 이 사용자 정의 종속성은 작동하는 것입니다. 따라서 사용자 지정 종속성은 캐시에 있는 코드이며 데이터 소스를 확인하기 위해 캐시에서 호출됩니다.

따라서 이 목표를 달성하면 점점 더 많은 데이터를 캐시하여 실질적인 이점을 얻을 수 있습니다. DB 종속성, 지금 메인프레임으로 작업하고 있기 때문에 SQL 종속성이나 Oracle 종속성이 작동하지 않습니다. 따라서 폴링은 얼마나 자주 수행되어야 합니까? 왜냐하면 저는 XNUMX분 안에 수백만 건의 레코드 트랜잭션이 진행되는 프로덕션 데이터로 작업하고 있기 때문입니다. 그래서 얼마나 자주. 그렇다면 얼마나 자주 여론 조사를 하는지 어떻게 알 수 있나요? 폴링은 구성 가능한 간격이며 호출되는 코드입니다. 따라서 각 설문조사에서 얼마나 많은 데이터를 확인할 것인지 결정합니다. 사용자 정의 종속성의 경우 실제로 특정 키를 확인하고 해당 키가 레거시 메인프레임에서 업데이트되었는지 여부를 확인하게 되기 때문입니다. 따라서 기본적으로 각 키에 대해 다음과 같이 됩니다. 이 키를 확인하세요. 이 키를 확인하세요. 사용자 정의 종속성의 경우. DB 종속성의 경우 이는 하나의 키가 아니라 전체 데이터 세트이며 다음과 같은 또 다른 기능이 있습니다. NCache 데이터 업데이터라고 합니다. 캐시 로더가 있습니다. 이는 코드가 존재하는 또 다른 서비스인 캐시 업데이터입니다. 그래서 캐시로더라는 기능이 있습니다. NCache여기서 실제로 모든 기능을 언급하지는 않았지만 캐시를 시작할 때 캐시를 로드하고 데이터 소스에서 캐시를 미리 로드할 수 있는 코드인 캐시 로더라는 기능이 있습니다. 따라서 메인프레임이 될 수 있습니다. 그러나 구성 가능한 간격마다 자동으로 코드를 호출하는 캐시 업데이터라는 기능도 있습니다. 그런 다음 해당 코드는 전체 데이터 소스를 확인하고 사용자 지정 논리와 변경된 데이터 또는 새 데이터에 따라 업데이트를 찾을 수 있습니다. 발생했거나 삭제된 데이터는 캐시를 업데이트할 수도 있습니다. 따라서 캐시는 데이터 소스와 동기화된 상태를 유지합니다. 기본적으로 이는 약 15초 간격으로 호출됩니다. 하지만 더 빠를 수도 있습니다. 필요에 따라 더 자주 발생하거나 덜 빈번하게 발생할 수 있습니다. 내가 당신의 질문에 대답했습니까? 더 많은 것이 있지만 생략하겠습니다. 그것에 대해서는 나중에 이야기하자.

Read-through 및 Write-through

따라서 해당 목표를 달성하면 점점 더 많은 데이터를 캐시하기 시작합니다. 그렇다면 다음은 '이제 얻었으니 어떤 다른 이점을 얻을 수 있을까요?'입니다. 그 다음으로 가장 중요한 것은 통독, 통독. 연속 읽기란 무엇입니까? 캐시 서버에 있는 것은 바로 귀하의 코드입니다. 따라서 캐시를 수행할 때 Get, Read-through가 코드라고 가정해 보겠습니다. NCache 당신은 IReadThruProvider. 세 가지 방법이 있습니다.

...
// Perform tasks like allocating resources or acquiring connections
public void Init(IDictionary parameters, string cacheId)
{
    object connString = parameters["connstring"];
    sqlDatasource = new SqlDatasource();
    sqlDatasource.Connect(connString == null ? "" : connString.ToString());
}

// Perform tasks associated with freeing, releasing, or resetting resources.
public void Dispose()
{
    sqlDatasource.DisConnect();
}

// Responsible for loading an object from the external data source.
public ProviderCacheItem LoadFromSource (string key)
{
    ProviderCacheItem cacheItem = new ProviderCacheItem(sqlDatasource.LoadCustomer(key));
    cacheItem.ResyncOptions.ResyncOnExpiration = true;
    // Resync provider name will be picked from default provider.
    return cacheItem;
}
...

캐시가 시작될 때 호출되고 캐시가 중지되면 삭제되는 Init가 있지만 가장 중요한 것은 이 로드입니다. 따라서 하중을 통과라고 합니다. 따라서 캐시에서는 이 메서드를 호출합니다. NCache 이 메소드를 호출하고 키를 전달합니다. 그리고 해당 키를 기반으로 데이터베이스로 이동하여 해당 항목을 가져옵니다. 따라서 이제 그렇게 하면 클라이언트에 대한 순효과는 다음과 같습니다. 캐시.가져오기, 캐시에는 항상 데이터가 있습니다. 물론 read-thru가 호출되는 것을 원하지 않는 경우에도 그렇게 할 수 있으며 구체적인 내용을 지정할 수 있습니다. 그러나 캐시에는 항상 데이터가 있습니다. 이것이 하나의 이점입니다. 따라서 지속성 레이어를 캐싱 계층에 통합하고 있습니다. 따라서 동일한 캐싱 계층을 사용하는 여러 애플리케이션이 있는 경우 동일한 지속성 코드를 유지할 필요가 없기 때문에 애플리케이션이 더욱 단순해지고 있습니다. 그들은 단지 캐시.가져오기 캐시에서 도메인 개체나 엔터티 개체를 가져옵니다. 따라서 캐시는 이제 EF와 훨씬 더 유사해 보입니다. 읽기 자체는 EF 기반일 수 있습니다.

읽기를 통해 수행할 수 있는 또 다른 작업은 이를 만료 및 데이터베이스 동기화와 결합할 수 있다는 것입니다. 그렇다면 이 두 가지 일이 발생하면 캐시에서 해당 데이터를 제거하는 대신 데이터를 다시 로드하는 것이 어떨까요? 왜냐하면 이를 제거하면 다음에 원할 때 애플리케이션이 이를 다시 로드해야 하기 때문입니다. 그리고 많은 경우 해당 데이터는 매우 자주 사용될 수 있습니다. 따라서 실제로 캐시에 다시 로드하고 싶습니다. 따라서 읽기는 코드를 통합할 뿐만 아니라 데이터베이스가 손상되지 않기 때문에 성능도 향상시킵니다. 많은 전자 상거래 상황에서 동일한 데이터에 너무 자주 액세스할 수 있으므로 캐시에서 해당 데이터를 제거하자마자 동일한 데이터에 대한 수천 개의 요청이 데이터베이스에 도달하게 되며 고객이 이에 대해 불만을 표시하는 것을 보았습니다. 각 데이터 항목이 만료되면 데이터베이스에 영향을 미치게 되는 수백만 개의 데이터 항목이 있기 때문에 이런 일이 너무 자주 발생합니다. 따라서 캐시를 확보한 후에도 전반적으로 데이터베이스에 대한 히트가 많이 발생했습니다. 따라서 이에 대한 대답은 만료 대신 다시 로드하는 것이었습니다. 따라서 다시 로드는 데이터가 캐시를 떠나지 않고 업데이트된다는 의미입니다. 따라서 캐시가 수행하는 한 번의 데이터베이스 호출을 제외하고 데이터베이스는 절대 건드리지 않습니다. 그래서 끝까지 읽는 것이 그런 식으로 매우 중요합니다.

다른 하나는 쓰기를 수행한다는 점을 제외하면 연속 읽기와 동일하게 작동하는 연속 쓰기입니다. 그리고 쓰기는 추가, 업데이트 또는 삭제가 가능함을 의미합니다. 이제 쓰기에는 또 다른 기능이 있습니다. 연속 기입의 이점 중 하나는 연속 읽기와 동일하며 코드를 통합한다는 것입니다.

후기 쓰기

두 번째 이점은 write-behind라고 합니다. 데이터베이스 읽기와 마찬가지로 데이터베이스 업데이트도 빠르지 않습니다. 데이터베이스 업데이트도 빠르지 않습니다. 따라서 데이터가 그다지 중요하지 않고 데이터베이스가 업데이트될 때까지 기다려야 하는 것이 아니라면 캐시만 업데이트하면 됩니다. 따라서 모든 애플리케이션 인스턴스는 이제 동일한 데이터를 가지며 캐시가 비동기 방식으로 데이터를 데이터베이스에 업데이트하도록 합니다. 그리고 캐시가 업데이트될 때까지 기다리지 않기 때문에 갑자기 애플리케이션의 성능이 향상됩니다. 따라서 write-behind에는 이러한 추가 이점이 있습니다. 그래서 대기열을 구축합니다. 다음의 경우 NCache 해당 대기열은 여러 서버에 복제되지만 다시 읽기-쓰루 쓰기-매우 중요한 기능입니다. 그리고 이것은 캐시 서버에 있는 코드이기도 합니다.

캐시 로더, 업데이트 프로그램, 사용자 정의 종속성, 연속 읽기, 연속 쓰기 등 여기에 존재하는 서버 코드를 모두 염두에 두시기 바랍니다. 이는 ... 다시 이러한 기능이 Java 측에도 존재한다는 것입니다. 그러니까, 그냥 그런 게 아니야. NCache 개발되었지만 다른 .NET 기본 캐시에서는 이러한 기능을 사용할 수 없습니다.

따라서 일단 시작하고 이 모든 것을 갖추고 나면 이렇게 하면 이제 캐시에 많은 데이터를 넣게 됩니다. 정말 혜택을 받기 시작했습니다. 그리고 캐시가 단지 키 값 액세스인 경우에는 그다지 친숙하지 않습니다. 따라서 캐시는 데이터를 가져오는 친숙한 방법을 수용해야 합니다.

데이터 그룹화

따라서 다음의 경우에는 NCache 당신이 할 수 있는 데이터가 많아요 그룹 및 하위 그룹, 태그, 이름표. SQL 또는 LINQ를 기반으로 검색할 수도 있습니다. 따라서 ''와 같은 작업을 수행할 수 있습니다.CUSTOMER.CITY = NEW YORK인 고객을 선택하세요.'. 그리고 이제 갑자기 많은 데이터 세트, 특히 더 필터링된 방식으로 반복해서 읽어야 하는 참조 데이터를 캐시에서 직접 가져올 수 있습니다. 그리고 이제 원하는 데이터에 대한 이점을 얻을 수 있습니다.

한 가지 명심해야 할 점은 SQL 검색을 수행할 때마다 전체 데이터 세트가 캐시에 존재해야 한다는 것입니다. 왜냐하면 이것은 데이터베이스로 이동하지 않기 때문입니다. 따라서 캐시만 검색합니다. 뉴욕에 있는 모든 고객을 나에게 제공한다고 가정해 보겠습니다. 모든 고객이 캐시에 없는 경우, 뉴욕의 모든 고객이 캐시에 없는 경우 NCache 또는 어떤 캐시도 올바른 데이터 세트를 다시 제공하지 않습니다. 따라서 내가 검색하면 사람들이 종종 혼동한다는 점을 명심해야 합니다. 캐시에 없으면 데이터베이스에서 가져옵니다. 그러나 SQL 쿼리는 데이터베이스 SQL 쿼리가 아닙니다. 이는 캐시 자체 쿼리입니다.

이제 많은 데이터가 있으므로 전체 데이터 세트, 특히 참조 데이터를 캐시에 보관할 수 있으며 캐시에서 이러한 데이터를 사용할 수 있습니다. 그러나 적어도 트랜잭션 데이터 내에는 캐시에 완전히 보관할 수 있는 하위 집합이 있습니다. 그러니까 그렇게 기다리세요. 따라서 이 모든 것을 염두에 두면 이제 캐시의 이점을 누릴 수 있습니다.

클라이언트 캐시

저는 이 기능을 한 가지 더 설명하겠습니다. 클라이언트 캐시. 사람들이 분산 캐시를 사용하기 시작할 때 정말 충격을 받는 것 중 하나는 특히 이전에 In-Proc 캐시를 사용했던 경우, 즉 독립형 캐시를 사용했다면 실제로 성능이 떨어진다는 것입니다. 그래서 많은 고객들이 우리에게 전화해서 이렇게 말했습니다. 성능이 향상될 것이고, 확장성이 향상될 것이며 실제로 성능이 저하될 것이라고 말합니다. 그리고 그 이유는 처음에는 독립형 캐시만 가지고 있었기 때문입니다. 크기는 제한되어 있었지만 캐시는 개체 형식이었고 개체는 힙에 보관되었으며 이제 캐시 클러스터로 이동해야 하며 직렬화, 역직렬화, 네트워크 이동이 있었고 속도가 훨씬 느렸습니다.

클라이언트 캐시

따라서 이 문제를 해결하기 위해 많은 캐시에 다시 '다수'라는 단어를 사용합니다. 왜냐하면 모든 Java 측 캐시, 즉 .NET 측에 '다수'가 있기 때문입니다. NCache 가지고 있습니다. 클라이언트 캐시라는 기능이 있습니다. Java 측에서는 캐시 근처라고 합니다. 이는 이전에 사용했던 것과 동일한 독립 실행형 캐시이며 의미도 동일하지만 이제 이 클러스터 캐시의 일부라는 사실을 인식합니다. 따라서 유지하는 데이터가 무엇이든 캐시 클러스터와 동기화된 상태를 유지합니다. 따라서 프로그래밍을 하지 않고도 연결만 하면 됩니다.

따라서 클라이언트 캐시의 도움으로 In-Proc 독립형 캐시 성능을 달성할 수 있으며 쓰기보다 읽기를 더 많이 수행하는 많은 데이터에 매우 좋습니다. 세션과 같은 용도로 이것을 사용하고 싶지 않습니다. 왜냐하면 세션에서는 하나의 읽기와 하나의 쓰기를 수행하기 때문입니다. 따라서 이점을 얻으려면 훨씬 더 많은 읽기와 쓰기를 수행해야 합니다.

동적 캐시 클러스터

따라서 구조적으로 캐시가 이제 데이터베이스와 같다는 것을 알아야 합니다. 이는 데이터 센터, 프로덕션 환경에 상주하며 애플리케이션에 고가용성이 필요한 경우 캐시도 고가용성이어야 합니다. 그렇지 않으면 문제가 발생합니다. 그리고 이를 수행하는 유일한 방법은 캐시가 100% 가동 시간을 보장하는 것입니다. 따라서 좋은 캐시는 다음과 같은 경우에 사용됩니다. NCache 그것은이 있습니다 동적 캐시 클러스터. PXNUMXP 구조로 되어있습니다. 서버를 추가하거나 삭제할 수 있으며 모든 것이 정상이며 아무것도 멈추지 않습니다. 캐시가 중지되지 않고 애플리케이션도 중지되지 않습니다.

동적 캐시 클러스터

복제를 통한 선형 확장성

그래서 우리는 파티션에 대해 이야기한 다음 토폴로지 이미. 복제는 지능적으로 수행되어야 합니다. 따라서 파티션 복제본의 경우 하나의 복사본만 만듭니다. 따라서 데이터는 복사본을 만들 때마다 더 많은 시간과 노력이 필요하기 때문에 두 위치에만 존재하며 두 위치 이상은 존재하지 않습니다. 속도가 느려집니다.

캐싱 토폴로지

분산 캐시의 WAN 복제

라는 기능도 있어요 WAN 복제. 현재 많은 사람들이 여러 데이터 센터를 보유하고 있습니다. 데이터베이스가 여러 데이터 센터를 처리할 수 있을 것으로 예상한다면 캐시는 어떻습니까? 이는 대부분의 Java 캐시에 있는 기능입니다. NCache 그것도 있지만 .NET 측에서만 가능합니다.

분산 캐시의 WAN 복제

NCache 대 Redis

마지막으로 한 가지만 말씀드리겠습니다. .NET 측에는 실제로 두 가지 옵션만 있기 때문입니다. 하나는 NCache, 하나는 Redis. Redis 실제로는 Linux 기반 캐시에 더 가깝지만 Microsoft가 Azure에서 이들과 파트너 관계를 맺은 이후 확실히 훨씬 더 인기를 얻었습니다. 그래서 공정한 비교를 하고 싶었습니다.

그건 그렇고, 저희 웹사이트에 가서 비교 페이지 가서 기능 비교를 통한 세부 기능 해당 문서와 우리 문서를 기반으로 모든 내용을 확인하세요. 그리고 이것은, 알다시피, 우리는 이것을 전혀 뱉어내는 것이 아니며 당신은 그것에 대해 좋은 판단자가 될 수 있습니다. 단지 작업을 더 쉽게 준비할 수 있도록 하기 위한 것입니다.

하지만 둘 다 오픈 소스이지만 NCache .NET 사용자를 위한 기본 .NET입니다. 전체 스택은 .NET입니다. NCache 서버 측에서는 사용할 수 없는 .NET 코드를 가질 수 있습니다. Redis. 그리고 Azure를 사용하고 있다면 Redis 서비스로서의 캐시로만 사용할 수 있지만 의도적으로 해당 모델을 선택하지 않았습니다. 캐시 서비스에서는 캐시가 블랙박스이기 때문입니다. 따라서 방금 이야기한 서버 측 기능이 없습니다. 그리고 VM 모델을 사용하면 완전한 제어가 가능합니다.

Redis 대 NCache - .NET 애플리케이션의 기능 수준 비교

우리 고객의 대부분은 자신의 통제권을 정말로 놓치고 싶어하지 않는 고급 기업입니다. 이는 SQL 데이터베이스와 SQL 서버와 같습니다. 그래서, NCache, 아시다시피, 여러분은 전체 환경을 제어하게 되며 여러분이 본 것처럼 매우 간단합니다. 그러나 다음을 통해 이러한 모든 서버 측 기능을 얻을 수 있습니다. NCache, 당신은 그렇지 않습니다. 왜냐하면 Redis 왜냐하면 당신은 접근할 수 없기 때문입니다.

Redis 대 NCache -클라우드 지원

따라서 다시 마음을 정하되 최소한 아키텍처에서 분산 캐시를 사용하십시오. 확장할 준비가 되었는지 확인하세요. 그것이 전체 목표입니다. 매우 감사합니다.

다음에 무엇을할지?

 

최신 업데이트를 받으려면 월간 이메일 뉴스레터에 가입하세요.

© 저작권 Alachisoft 2002 - . 판권 소유. NCache 는 Diyatech Corp.의 등록상표입니다.