우연히 SQLER에서 Windows Azure(이하 윈도우 애저) 온라인 캠프를 진행한다는 소식을 접하고 새롭게 바뀐 윈도우 애저 UI등 기능을 살펴볼 좋은 기회라 생각이 되어 참가 하게 되었다. 이전에는 실버라이트 기반으로 인하여 사용환경이 조금은 무겁게 느껴지던 것이, 현재는 HTML 기반으로 요즘 Microsoft의 UX 트랜드가 잘 적용되어 있으며, 사용성 측면에서도 과거에 비해 많이 향상된 것을 볼 수 있다.

 

윈도우 애저는 IaaS(Infrastructure as a Service)를 가장 잘 지원하는 플랫품 중의 하나로 볼 수 있다. IaaS에 대한 설명은 위키의 Cloud computing 혹은 SQLER의 IaaS, PaaS, SaaS - 누구나 클라우드를 말한다. 글을 참고 하면 많은 도움이 될 수 있을 것이다.

 

이번 온라인 캠프에서 제공된 서비스는 8코어, 14GB메모리의 SQL Server용 빵빵한 VM을 제공받게 되었다.(물론 단기 몇 일 되지 않지만…)

그럼 먼저 관리 포털 메인 화면을 살펴 보자. 예전 보다는 확실히 직관적인 UX를 제공하고 있다.

1.png

[관리 포털 메인]

 

관리 포털에서는 자신이 제공받고 있는 서비스 전체 목록을 확인 할 수 있으며, 항목을 선택할 경우 세부 정보 및 설정을 할 수 있다. 다음은 제공받은 SQL Server VM의 상세 화면이다. 현재 서버의 중요 정보를 Dashboard로 표시해 주며, 각VM에 대한 각종 주요 정보를 한눈에 확인 할 수 있다.

2.png

[VM상세 정보 화면]

 

  1. 새로운 VM을 생성 가능하다. VM을 미리 정의된 갤러리를 통해 쉽게 생성할 수 있는 기능을 제공해 주고 있다.

     

         3.png

[VM 생성 갤러리 화면]

 

  1. VM이므로 당연히 RDP를 통해 접속하여 많을 설정을 직접 할 수 있다. 아이콘을 선택하면 RDP 접속을 위한 기본정보가 입력된 파일을 다운로드 받게 된다.
  2. VM을 재시작시 사용
  3. VM을 종료
  4. VM을 삭제
  5. 방화벽의 포트를 여는 것처럼 해당VM의 접근을 허용할 포트를 지정해야 한다. 처음 VM을 생성하면 RDP를 위한 3389 포트가 기본으로 설정이 되어 있다. 한가지 유의할 점은 SQL서버를 외부에서 접근하려면(Management Studio 등) SQL 기본 포트인 1433을 명시적으로 허용하는 작업을 해 주어야 한다.

     

         4.png

 

         5.png

[신규 Endpoint 추가]

 

VM 옵션을 변경할 경우 다음과 같이 각 진행사항을 비주얼하게 확인할 수 있는 화면을 제공해 주고 있어, 진행사항을 쉽게 확인 가능하다. ①번을 클릭하게 되면 목록을 토글할 수 있다.

6.png

 

[외부에서 SQL Sever 접근 설정]

SQL Server용 VM을 처음 생성하고 나면, 기본적으로는 외부에서 접근 할 수 있도록 설정이 되어 있지 않다. 그러므로 사용자가 직접 접근 가능 하도록, 서버의 방화벽 및 VM Endpoint 설정 등을 해 주어야 한다. 설정에 대한 자세한 내용은 Windows Azure 사이트의 Provisioning a SQL Server Virtual Machine on Windows Azure 에 잘 나와 있지만, 중요한 부분만 다시 살펴 보도록 하겠다. 추가적인 자세한 내용은 해당 링크를 꼭 참고해 보기를 바란다.

 

  1. VM Endpoint 설정
    1. 상단에 Endpoint 설정 설명과 같이 SQL 기본 서비스 포트인 TCP 1433을 추가해 준다.

       

  2. 처음 생성된 VM의 SQL Server는 서버 인증을 기본값이 윈도우 인증만을 허용하고 있다. 그러므로 아래 그림과 같이 SQL Server 와 윈도우 인증 모두 허용하는 모드로 변경을 해 주어야 한다. 인증 방식을 변경하였으면 서버를 Refresh하여 설정 내용이 반영 되도록 처리 한다.

     

    7.png

    [서버 인증 모두 변경]

     

    8.png

    [서버 Refresh]

     

  3. DB 접근에 사용할 SQL Sever 계정을 하나 생성 한다.
  4. 서버 윈도우 방화벽의 인바운드 규칙에 TCP 1433을 추가한다.

모든 설정이 완료 되었으면 로컬에서 SQL Server Management Studio 등으로 정상적으로 접속이 되는지 확인해 본다.

 

짧은 기간이라 많이 살펴 보지는 못했지만, VM 이외에 DB, 스토리지 등 다양한 클라우드 서비스 등이 존재하며, 확실치 초기 버전에 비해 사용측면에서는 안정화 및 편의성이 많이 향상이 된 듯 하다. 특히 기존 별도로 존재하던 SQL Server를 만약 VM형식의 SQL Server로 이전하려 한다면, 기존 서버 설정과 완전히 동일하며, 프로그램에서는 연결문자열 정도 수정만으로 쉽게 데이터 영역을 이전할 수 있어 많은 강점을 가질 수 있을 것으로 생각이 된다.

 

한가지 아쉬운 점은 아직 지역화가 되지 않아 VM 및 메뉴가 모두 영문만 제공 되는 것이다. 하지만 이 부분은 시간이 해결해 주리라 믿는다.

 

[Appendix – Azure VM SQL Server에서 Entity Framework로 처리]

그래도 .NET 개발자 인지라, Entity Framework로 처리하는 부분을 테스트 해봤다. 당연히 VM은 일반 서버화 동일 하므로 프로젝트에서 Entity Framework 설정 후 작업을 진행하면 된다.

테스트를 위하여 VM의 SQL Server에 Table을 다음과 같이 하나 만들었다. 그리고 Entity 생성 후 많을 데이터를 입력해 보았다. (Entity 생성하는 부분은 이미 잘 알고 있다고 가정한다.)

 

9.png

 

 

static void EntityAdd()

{

    try

    {

        using (TransactionScope txScop = new TransactionScope(TransactionScopeOption.RequiresNew))

        {

            using (TestDBEntities context = new TestDBEntities())

            {

context.Configuration.AutoDetectChangesEnabled = false;

                context.Configuration.ValidateOnSaveEnabled = false;

 

                var now = DateTime.Now;

 

                var itemList = new List<BulkTable>();

 

                for (int i = 10000; i < 11000; i++)

                {

                    var newItem = new BulkTable

                    {

                        Seq = i,

                        Value = i.ToString(),

                        CreateDate = now

                    };

 

                    context.BulkTable.Add(newItem);

                }

                       

                Stopwatch watch = new Stopwatch();

                watch.Start();

 

                context.SaveChanges();

                       

                watch.Stop();

 

                Console.WriteLine("Entity Framework 완료 : {0} ms", watch.ElapsedMilliseconds);

            }

 

            txScop.Complete();

        }

    }

    catch (Exception ex)

    {

        Console.WriteLine(ex.ToString());

    }

}

 

[Entity Framework를 이용한 데이터 입력]

 

약 1000개의 데이터를 입력해 보았다. 지금 얘기하려는 부분은 Azure에 해당하는 부분이 아니라 Entity Framework 자체에 대한 부분이다.

입력이 아주 느리게 진행되는 것을 보일 것이다. 실무에서 약 20만건을 한번에 입력해야 할 일이 발생하였다. 처음에는 평소와 마찬가지로 위 코드와 비슷하게 작성을 하고 실행하였지만 10분을 기다려도 작업이 완료 되지 않았다. 뭔가 문제가 있는 것이다.

 

해결책을 알아 보기 위해 열심히 google을 검색하던 중 재미있는 글을 하나 발견하게 되었다. Entity Framework를 이용한 Bulk 입력이다. Problem with Bulk insert using Entity Framework 에서는 위와 같이 단순 객체 생성 후 SaveChanges() 했을 때의 문제점에 대해 해결책으로 Entity는 유지하고 SqlBulkCopy를 이용한 방법을 얘기하고 있다.

 

특히 예제에서 Entity로 생성된 리스트를 IDataReader 형태로 변환을 하는 AsDataReader() 메소드를 사용하는데 이 메소드는 Microsoft에서 제공하는 LINQ Entity Data Reader 라는 것을 사용하였다. SqlBulkCopy는 ADO.NET에서 테이블 단위로 빠르게 입력작업을 위한 객체로 Entity Framework의 정의된 Entity 자체를 사용 가능하게 한 것이다. 특히 별도 ADO.NET 코드를 작성한 것이 아니라, 커넥션 정보, 테이블 정보 등을 기존 정의된 Entity Framework의 정보를 이용한다는 것이 중요하다. 실행 결과는 정말 경이적이었다. 일반적인 위에서 작성한 방식과 비교하면 실행속도 면에서 많은 차이를 피부로 느낄 수 있을 것이다. 꼭 실제 작성하여 실행해 보기를 권한다.

 

 

static void BulkAdd()

{

    try

    {

        using (TransactionScope txScop = new TransactionScope(TransactionScopeOption.RequiresNew))

        {

            var now = DateTime.Now;

 

            var bulkItem = new List<BulkTable>();

 

            for (int i = 0; i < 10000; i++)

            {

                var newItem = new BulkTable

                {

                    Seq = i,

                    Value = i.ToString(),

                    CreateDate = now

                };

 

                bulkItem.Add(newItem);

            }

 

            TestDBEntities entityContext = new TestDBEntities();

 

            Stopwatch watch = new Stopwatch();

            watch.Start();

 

            using (var dbConn = entityContext.Database.Connection as SqlConnection)

            {

                dbConn.Open();

 

                using (SqlBulkCopy bulk = new SqlBulkCopy(dbConn))

                {

                    bulk.DestinationTableName = "dbo.BulkTable";

                    bulk.WriteToServer(bulkItem.AsDataReader());

                }

            }

 

            txScop.Complete();

 

            watch.Stop();

 

            Console.WriteLine("SqlBulkCopy 완료 : {0} ms", watch.ElapsedMilliseconds);

 

            txScop.Complete();

        }

    }

    catch (Exception ex)

    {

        Console.WriteLine(ex.ToString()); 

    }

}

 

[SqlBulkCopy를 이용한 입력]

 

비록 Azure와는 직접적인 관계는 없지만, Entity Framework 작업시 Entity Framework "만"을 고집하기 보다는 현재 작업에 가장 효율적인 부분을 찾아 적용하는 것이 중요할 듯 하다. 보통 새로운 기술이 나오고 적용을 생각하게 되면 전체를 꼭 그것만 사용해야 된다는 강박관념이 있는 것 같다. 개발 표준을 세우는 것은 맞지만, 그렇다고 꼭 모든 부분 하나만 써야 할 필요는 없을 것 같다. 농담으로 이런 얘기를 하지 않는가? "그때 그때 달라요."

 

이상으로 삼일 간 살펴본 Windows Azure 온라인 캠프와 덧 얘기(?)를 마치도록 하겠다.





profile

Microsoft Visual C# MVP since 2007

Microsoft Certified Trainer