기본 콘텐츠로 건너뛰기

[SolrCloud] ZooKeeper와 SolrCloud를 Tomcat7 에 설정해 보기

[ 참고 및 주의 사항 ]
여기에 정리된 내용은 원문을 기준으로 여러 가지 테스트와 문제점의 검토 및 해결책을 찾으면서 나름대로 정리한 내용으로 오역과 잘 못 이해하고 정리한 부분이 있을 수 있습니다.
또한 원문의 Solr 버전이 지금 테스트를 진행하고 있는 4.10.2 버전과 다르기 때문에 내용을 잘 확인하면서 진행해야 합니다.

SolrCloud Collection 디자인

SolrCloud 를 운영하기 위해서는 Cluster를 디자인을 하는 것이 가장 중요한 부분이다. 개념적으로는 SolrCloud Cluster 내에서 Collection 과 Shard 는 논리적인 요소로 여러 개의 물리적인 Core 들의 집합을 형성하기 위한 것이다. 샘플 테스트를 위해서 다음과 같이 Cluster를 디자인 한 것으로 가정한다.
  • Cluster에는 단일 Collection을 관리하고 이름을 test_collection 이라고 한다.
  • ZooKeeper Ensemble 은 3개의 복제된 서버들을 사용하는 것으로 한다.
  • Replication Factor를 3으로 지정하여 SolrCloud 에 3개의 Node를 구성한다.
  • SolrCloud 에 3개의 Shard 를 구성한다.
  • 3개 노드의 3개 Shard에 복제 본들을 수동으로 배포한다.

필요 항목들

이 작업을 테스트하기 위해서는 다음과 같은 구성이 필요하다.
Notes
위의 디자인된 SolrCloud 는 단일 장비에서 테스트를 진행한다. 실제로는 여러 장비에 분산하여 운영되는 것이 정상이다.

샘플 디렉터리 구성

단일 장비에서 테스트를 진행할 것이기 때문에 “D:\SolrCloud” 를 기본 경로로 사용한다.
  • Node 구성을 위한 각 Solr Home 폴더
    D:\SolrCloud\solr\home1
    D:\SolrCloud\solr\home2
    D:\SolrCloud\solr\home3
  • Node 동작을 위한 Tomcat Home (Catalina Base)
    D:\SolrCloud\web1
    D:\SolrCloud\web2
    D:\SolrCloud\web3
  • Collection 구성에 사용할 Configuration Directory
    D:\SolrCloud\default_config
  • ZooKeeper에 명령을 처리할 zkCLI 폴더
    D:\SolrCloud\solr-cli

샘플 구성도

디자인된 설정을 기준으로 개략적인 그림을 그려보면 다음과 같이 표현할 수 있다.
SolrCloud 샘플 구성도

ZooKepper Ensemble 구성

Multiple Server를 기준으로 ZooKeeper Cluster를 구성하는 방법은 여기를 참고해서 구성하도록 한다.

zkCLI 명령을 통한 ZooKeeper 명령 처리

SolrCloud에서 사용할 설정 집합 (Configuration Sets)는 zkCLI 명령을 통해서 쉽게 ZooKeeper Server 로 Upload / Download / Collection Link 등의 작업을 처리할 수 있다. 기본적으로 아래와 같은 구성만 있으면 처리가 가능하다.
  • Apache Solr 4.10.2 War
  • lib 폴더의 jar 들
zkCLI 를 사용하기 위해서는 다음과 같이 작업을 처리하면 된다.
  1. 다운로드한 Solr 4.10.2 버전의 압축을 풀면 “example\webapps” 폴더에 solr.war 파일이 존재한다. 이 war 파일의 압축을 해제한다.
  2. 샘플에서 사용할 “D:\SolrCloud” 폴더 밑에 “solr-cli” 폴더를 만들고 solr.war 의 압축을 해제한 폴더에서 “WEB-INF\lib” 폴더의 모든 jar 들을 solr-cli 폴더로 복사한다.
  3. 로그 처리를 위해서 solr 4.10.2 버전의 압축을 해제한 폴더 밑의 “example\lib\ext” 폴더에 존재하는 로그 관련 jar 파일들을 모두 “solr-cli” 폴더로 복사한다.
  4. 이제 zkCLI 사용을 위한 준비가 완료되었다.

SolrCloud 에서 Collection 구성에 사용할 Configuration 파일 처리

각 조직에서는 조직에 필요한 요구들과 요건들을 가지고 인덱스를 구성하게 된다. 그리고 구성을 위한 설정 파일들을 기준으로 Solr을 운영하게 되므로 SolrCloud도 이와 다르지 않다. 다만 여러 서버들에 대해서 동일한 설정 파일들을 공유하는 것이 다를 뿐이다. 설정 파일의 최소한은 schema.xml (필드들과 데이터 구조에 대한 설정) 과 solrconfig.xml (토큰 처리기, 분석기, 요청 처리기 등에 대한 설정) 이며 추가적으로 stopword, Boosting, Blocking, Synonyms 등의 파일을 사용하게 된다.
  1. 샘플을 구성하기 위해서 공통으로 사용할 설정 파일들을 관리할 “default-config” 폴더를 “D:\SolrCloud” 폴더 밑에 생성한다.
  2. 우선 Solr 4.10.2 압축을 해제한 폴더에서 “example\solr\collection1\conf” 에 있는 모든 파일을 “default-config” 폴더로 복사한다.
기본 테스트를 위한 환경 설정 준비는 완료 되었다. (지금은 기본 테스트용 설정이지만 실제 단독 Solr 서버로 운영하고 있는 설정이 있다면 그 설정을 그대로 복사하면 된다)

Solr 설정 집합을 ZooKeeper에 Upload하기

zkCLI 를 사용하기 위해서는 아래와 같은 사항들을 파악하고 있어야 한다.
  • “zkhost” 파라미터에 사용할 ZooKeeper Host addresses 와 Client Port numbers (ZooKeeper 구성에서 localhost 에서 Client Port 를 2181, 2182, 2183 으로 설정했다)
  • “confdir” 파라미터에 사용할 설정 파일 디렉터리 경로 (여기서는 테스트이므로 “D:\SolrCloud\default-config”)
  • ZooKeeper와의 연동에 사용할 설정 파일 집합에 대한 식별 명. (여기서는 테스트이므로 “testconf” 라고 사용한다)
위의 정보를 기준으로 아래와 같이 처리를 진행한다.

Configuration Set Upload

ZooKeeper 서버들로 Configuration Sets 를 Upload 하기 위해서는 아래와 같은 zkCLI 명령을 수행해야 한다.
java -classpath .;D:\SolrCloud\solr-cli\* org.apache.solr.cloud.ZkCLI -cmd upconfig -zkhost localhost:2181,localhost:2182,localhost:2183 -confdir D:\SolrCloud\default_config -confnme testconf
Notes
  • -classpath 를 지정할 때 경로 구분자가 윈도우 환경에서는 “;” 리눅스 계열에서는 “:” 로 다르므로 정확하게 구분해서 처리해야 한다.
  • 또한 Java Application 으로 동작하는 것이기 때문에 옵션과 Namespace 및 Class 이름에 대한 대소문자를 명확하게 지정해 주어야 한다.
별다른 오류 메시지가 없다면 잠시 동안 default_config 폴더에 존재하는 모든 파일들이 ZooKeeper Server 들로 Upload 된 후에 종료된다. 만일 오류 메시지가 발생한다면 관련된 오류를 해결해야 한다.

Configuration Set 정보를 Collection에 연결

주의 사항
원문에서는 linkconfig 를 통해서 Configuration Sets 와 Collection 의 이름 (아직 생성되지 않은) 을 연결해 놓으면 나중에 Collection을 생성할 때 confname 파라미터를 설정하지 않아도 설정을 가져다 사용하는 것으로 설명하고 있다.
그러나 실제 테스트를 진행한 결과 Collection 을 생성할 때 Solr 에서 null 메시지의 알 수 없는 오류가 발생하고 ZooKeeper 관련 로그를 확인하면 “NodeExists of collection/test-collection” 이라는 오류가 발생하는 것을 알 수 있다. 물론 linkconfig 과정을 생략하고 생성을 하면 Collection 이 잘 만들어 진다.
따라서 linkconifg 를 통해서 연결할 때 ZooKeeper 의 collections 에 test-collection 노드 정보가 미리 생성되어 문제가 발생하는 것으로 파악이 된다. 아직 해결 법은 찾지 못했으나, linkconfig 를 제외하고 Collection 생성 시점에 confname 파라미터를 설정하면 정상적으로 구성할 수 있다.
이 부분은 Solr 버전에 따른 변경으로 인한 것일 수 있다.
아직 Collection을 만들지는 않았지만, Upload된 설정 집합을 적용(링크)하는데 사용할 Collection의 이름을 “test-collection” 이라는 이름으로 정보를 구성해 놓도록 한다.
java -classpath .;D:\SolrCloud\solr-cli\* org.apache.solr.cloud.ZkCLI -cmd linkconfig -collection test-collection -confname testconf -zkhost localhost:2181,localhost:2182,localhost:2183
위의 명령은 이전에 Upload 한 Configuration Sets 의 이름 (testconf) 을 기준으로 “test-collection” 이라는 Collection 이 생성될 때 Configuration Sets 의 내용을 기준으로 연결하라는 것을 ZooKeeper Server 에 알려주는 것이다.
Notes
이 명령들을 수행하는 이유는 ZooKeeper 가 이런 정보들을 마치 디렉터리와 파일의 구조처럼 관리하기 때문에 사용할 이름들 (Configuration Sets, Collection) 을 기준으로 미리 구조를 만들어 놓아야 하기 때문이다.

ZooKeeper에 연결해서 Upload된 Configuation Set 검증 및 Collection 경로 확인

위의 ZooKeeper 설정 샘플에서 3 대의 ZooKeeper 서버를 설정했으므로 각 서버 별로 아래의 단계에 따라서 접속 및 검증을 수행하면 된다.
Notes
zkCLI 는 Command Line Interface 이기 때문에 자체적인 명령 처리 구조를 가진다. 마치 Telnet 과 같이 사용한다고 생각하면 된다. 그리고 각종 명령어를 확인하기 위해서는 “?” 를 입력하고 엔터를 치면 사용할 수 있는 명령들을 확인할 수 있다. Path 지정 방식 등은 무조건 ‘/’ 문자로 시작해야 한다.
  • ZooKeeper 에 연결하기
    > cd D:\SolrCloud\ZooKeeper\zk-server1\bin
    > zkCli.cmd -server localhost:2181
    Connecting to localhost:2181
    Welcome to ZooKeeper!
    JLine support is enabled
    [zk: localhost:2181(CONNECTING) 0]
    WATCHER::
    
    WatchedEvent state:SyncConnected type:None path:null
  • Upload된 설정 집합과 Collection 경로 확인하기
    [zk: localhost:2181(CONNECTED) 1] ls /
    [configs, collections, zookeeper]
    [zk: localhost:2181(CONNECTED) 2] ls /configs
    [testconf]
    [zk: localhost:2181(CONNECTED) 3] ls /configs/testconf
    [admin-extra.menu-top.html, currency.xml, protwords.txt, mapping-FoldToASCII.txt, solrconfig.xml, ...]
    [zk: localhost:2181(CONNECTED) 4] ls /collections
    [test-collection]
    [zk: localhost:2181(CONNECTED) 5] ls /collections/test-collection
    []
위의 실행 결과와 같이 설정 파일들과 식별 명 및 Collection과 관련된 정보들이 ZooKeeper 상에 적용되어 있는 것을 확인할 수 있다. 마지막에 /collections/test-collection 의 결과가 [] 인 것은 아직 Collection 이 생성되지 않았기 때문에 정보가 없을 뿐이다.

Tomcat7 환경에 SolrCloud 배포하기

ZeeKeeper 설정과 SolrCloud 운영을 위해서 이제는 Tomcat7 을 설정한다. 아래와 같이 작업을 진행하면 된다. 여기서는 Tomcat의 설치 버전이 아닌 Zip 버전을 이용해서 처리한다. 이 부분에 대한 개념은 “하나의 웹 어플리케이션을 여러 개의 인스턴스로 구동해 보기” 를 참고하도록 한다.

디렉터리 구조 생성

제일 위에서 디자인 했던 것과 같이 디렉터리를 구성하도록 한다.
  • Tomcat7 폴더
    • D:\SolrCloud\web1
    • D:\SolrCloud\web2
    • D:\SolrCloud\web3
  • Solr Home 폴더
    • D:\SolrCloud\solr\home1
    • D:\SolrCloud\solr\home2
    • D:\SolrCloud\solr\home3

Tomcat7 과 Solr 다운로드 및 필요한 파일 배포

Tomcat7 과 Solr 4.10.2 버전을 다운로드 해서 압축을 해제한다.
  • tomcat7 압축 해제한 폴더의 내용을 모두 web1, web2, web3 에 복사하여 배포한다.
  • solr 4.10.2 압축 해제한 폴더의 “example\webapp\solr.war” 파일을 “web1\webapps\solr.war”, “web2\webapps\solr.war”, “web3\webapps\solr.war” 로 복사하여 배포한다.
  • 로그 처리에 필요한 라이브러리들을 “example\lib\ext*” 를 “web1\lib”, “web2\lib”, “web3\lib” 로 복사하여 배포한다.

필요한 환경 설정

Tomcat7 구동에 필요한 설정들을 정의할 setenv.bat” 파일을 생성한다. 아래와 같이 구동에 필요한 정보를 구성하도록 한다. 이 파일들은 web1\bin, web2\bin, web3\bin 에 모두 동일하게 생성한다.
set JAVA_HOME="%JAVA_HOME%"

rem JVM을 Server 모드로 구동 set JAVA_OPTS="%JAVA_OPTS% -server" rem JVM 메모리 설정 set JAVA_OPTS="%JAVA_OPTS% -Xms128m -Xmx2048m" set JAVA_OPTS="%JAVA_OPTS% -XX:PermSize=64m -XX:MaxPermSize=128m -XX:+UseG1GC" rem JVM Timezone and encoding set JAVA_OPTS="%JAVA_OPTS% -Duser.timezone=UTC -Dfile.encoding=UTF8"

rem Solr Options rem solr.solr.home : Solr Home 경로로 1,2,3 서버의 Home 경로를 각각 지정 rem host : Solr 서비스할 Host Name 을 지정한다. 여기서는 localhost 사용 rem port : Solr 포트로 1,2,3 서버를 각각 지정 (ex. 7070, 8080, 9090) rem hostContext : WebApp의 Context 명 rem zkclientTimeout : ZooKeeper 연결에 대한 클라이언트 타임아웃 rem zkhost: ZooKeeper ensmeble 의 Host명과 클라이언트 접속 포트를 모두 지정 set SOLR_OPTS="-Dsolr.solr.home=D:\SolrCloud\solr\home1 -Dhost=localhost -Dport=7070 -DhostContext=solr -DzkClientTimeout=20000 -DzkHost=localhost:2181,localhost:2182,localhost:2183"

# 옵션 통합 set JAVA_OPTS = “%JAVA_OPTS SOLR_OPTS”

Notes
만일 ZooKeeper에 별도의 디렉터리로 Solr 설정들을 관리하는 경우라면 -DzkHost 파라미터를 지정할 때 가장 마지막에 지정한 Host 정보에 경로명을 명시적으로 지정하는 것이 좋다.
-DzkHost=localhost:2181,localhost:2182,localhost:2183/solr_conf

Solr 구성 파일 (solr.xml) 설정

Solr Home 폴더에 아래와 같은 내용을 가지는 solr.xml 파일을 생성한다. 단, 아래의 설정은 Solr 4.4.0 부터 적용된다.

<solr>
    
    <solrcloud>
        <str name="host">${host:}str>
        <int name="hostPort">${port:}int>
        <str name="hostContext">${hostContext:}str>
        <int name="zkClientTimeout">${zkClientTimeout:}int>
        <bool name="genericCoreNodeNames">${genericCoreNodeNames:true}bool>
    solrcloud>
    
    <shardHandlerFactory name="shardHandlerFactory" class="HttpShardHandlerFactory">
        <int name="socketTimeout">${socketTimeout:0}int>
        <int name="connTimeout">${connTimeout:0}int>
    shardHandlerFactory>
solr>
만일 4.3.1 버전이라면 아래와 같이 구성하여야 한다.

<solr persistent="true">
    
    <cores adminPath="/admin/cores" defaultCoreName="collection1" host="${host:}" hostPort="${port:}"
        hostContext="${hostContext:}" zkClientTimeout="${zkClientTimeout:}">
    cores>
solr>
위의 solr.xml 파일을 home2, home3 에도 복사해 놓는다.

권한 설정

윈도우 환경이라면 별다른 문제가 없을 수 있지만, 리눅스 계열이라면 샘플에서 사용하는 경로에 권한을 설정해 주어야 한다. 예를 들면 다음과 같다. (루트 폴더 이하 모든 폴더에 관리자는 모두, 그룹과 일반 사용자는 실행만 가능하고, Tomcat 구동을 위한 Shell 실행 권한 추가)
chmod -R 755 /users/solrcloud
chmod +x /users/solrcloud/web*/bin/*.sh

Tomcat7 구동을 위한 설정

단일 서버에서 여러 개의 Tomcat을 구동할 것이기 때문에 각 web1, web2, web3 의 conf 폴더에서 server.xml 의 Port 정보를 변경하도록 한다. (Port 는 Shutdown, Http Port 만 처리하면 되고 AJP Connector는 여기서는 사용하지 않는다) 아래의 내용은 변경 대상을 설정한 것이다.
  • web1 의 server.xml
    Port No : 7070
    Shutdown Port No : 7050
    AJP Connector : comment out
  • web2 의 server.xml
    Port No : 8080
    Shutdown Port No : 8050
    AJP Connector : comment out
  • web3 의 server.xml
    Port No : 9090
    Shutdown Port No : 9050
    AJP Connector : comment out

Tomcat7 구동

web1, web2, web3 의 설정이 되었으므로 각 폴더의 bin 경로에서 Tomcat을 구동하도록 한다.
D:\SolrCloud\web1\bin\startup.cmd
D:\SolrCloud\web2\bin\startup.cmd
D:\SolrCloud\web3\bin\startup.cmd

Solr 구동 결과 확인

이제 정상적으로 구동이 되었는지 확인하기 위해서 아래와 같이 사이트에 접속을 해 보도록 한다.
http://localhost:7070/solr
http://localhost:8080/solr
http://localhost:9090/solr
각 사이트에서 Solr Admin UI 를 확인할 수 있으며 아래의 그림과 같이 아직 Solr Core 가 존재하지 않는다는 메시지를 확인할 수 있다.
No cores available

SolrCloud 환경에서 Collection과 Shard(s)와 Replica(s) 생성하기

이제 CoreAdmin API 를 이용해서 Collection, Shard(s), Replica(s) 및 Replication Factor를 설정하면 된다. 이 API 들을 통해서 특정한 Solr Node의 복제 본에 대한 Core를 조정할 수 있다.

Collection 생성과 파라미터 설정

  • action - CREATE
  • collection name - test-collection
  • number of shards - 3 (Partitioning 처리 수)
  • replication factor - 3 (Collection의 문서 복제 본의 수)
  • maxShardsPerNode - 3 (Solr 4.2 부터 지정 가능하고, Node 당 최대 Shard 수)
  • confname - testconf
이 정보를 web1 에서 운영 중인 Solr 로 요청을 하면 된다.
http://localhost:7070/solr/admin/collections?action=CREATE&name=test-collection&confname=testconf&numShards=3&replicationFactor=3&maxShardsPerNode=3
위의 명령이 수행되면 test-collection 이라는 Collection이 생성되고 각 SolrCloud 구성 Node에 Shard 가 생성이 되며, 각 Shard 에 Core 가 배정되게 된다.
Notes
만일 Solr Admin UI 이 Logging 에서 null 메시지의 오류가 발생한다면 위의 Configuration Set 정보를 Collection에 연결에 있는 “주의 사항” 을 다시 한번 읽어 보기 바란다.
정상적으로 수행이 완료되면 Solr Admin UI 의 Cluster 메뉴를 통해서 아래의 그림과 같이 Shard 와 Node 들이 생성되어 Leader 와 Replica 로 구성된 것을 알 수 있다.
SolrCloud 에서 Collection 생성 후에 구성된 Shards
그리고 Solr Admin UI 에서 Core Admin 메뉴를 확인해 보면 아래의 그림과 같이 기본적인 Shard 기준으로 Core 가 생성된 것을 확인할 수 있다.
SolrCloud 에서 Collection 생성 후에 구성된 Cores
Notes
Collection을 생성할 때 “numShard=3” 와 “replicationFactor=3” 를 지정했기 때문에 3 * 3 = 9 개의 Core 가 3 개의 Solr Node (7070, 8080, 9090) 에 자동으로 생성되어야 정상이다.
이를 확인하기 위해서는 Solr Admin UI 의 Core Admin 을 각각 확인해도 되지만, Solr Home 구성을 해 놓았기 때문에 탐색기에서 아래와 같이 Core 가 구성이 되었는지 확인 해 보면 된다.
SolrCloud 에서 Collection 생성 후에 구성된 9개의 Cores

Shard 복제본(Replicas) 를 생성하고 SolrCloud의 Node에 분산하기

Notes
위에서 확인한 것과 같이 Collection 이 생성될 때 numShards 와 replicationFactor 를 통해서 자동으로 생성되므로 아래의 작업을 진행할 의미는 없다. 그러나 수동으로 생성을 해야 한다면 아래와 같이 요청을 처리하면 된다.
이 작업은 Solr 버전에 따라서 다를 수 있으며 4.10.2 에서는 따로 작업할 필요가 없다.
복제본(Replica)을 생성하기 위해서 특정한 Solr Node를 선택하고 Shard 의 이름을 지정한다.
  • Shard 1 Replica
    http://localhost:7070/solr/admin/cores?action=CREATE&name=shard1-replica-1&collection=test-collection&shard=shar1
    http://localhost:9090/solr/admin/cores?action=CREATE&name=shard1-replica-2&collection=test-collection&shard=shar1
  • Shard 2 Replica
    http://localhost:8080/solr/admin/cores?action=CREATE&name=shard2-replica-1&collection=test-collection&shard=shar2
    http://localhost:9090/solr/admin/cores?action=CREATE&name=shard2-replica-2&collection=test-collection&shard=shar2
  • Shard 3 Replica
    http://localhost:7070/solr/admin/cores?action=CREATE&name=shard3-replica-1&collection=test-collection&shard=shar3
    http://localhost:8080/solr/admin/cores?action=CREATE&name=shard3-replica-2&collection=test-collection&shard=shar3
위의 명령과 같이 Shard1, Shard2, Shard3 에 대해서 Replica 1, 2 를 원하는 서버 Node 에 대해서 지정하여 배포하면 된다. 위의 명령이 제대로 수행되면 아래의 그림과 같이 Solr Admin UI 에서 Cluster 메뉴를 선택하면 구성된 내용을 확인할 수 있다.
그리고 이렇게 처리된 정보들은 각 서버의 Solr Home (home1, home2, home3) 에 존재하는 solr.xml 파일에 기록이 남겨지게 된다. 이를 기준으로 다음 Solr 실행 시에 똑같은 구성으로 동작할 수 있게 된다.
Notes
원문에서는 Solr.xml 에 Core에 대한 정보가 설정되는 것으로 설명하고 있지만 4.10.2 버전에서는 solr.xml 파일을 수정하지 않고 생성된 각 Core 폴더에 보면 core.properties 파일이 생성된 것을 확인할 수 있다.

샘플 문서들을 Indexing 하기

Solr 4.10.2 압축 해제 폴더에 보면 example\exampledocs 에 보면 샘플로 사용할 문서들이 존재한다. 이 문서 정보를 기준으로 생성한 Collection 에 문서를 추가해 보도록 한다.
java -Durl=http://localhost:7070/solr/test-collection/update -jar post.jar ipod_video.xml
java -Durl=http://localhost:8080/solr/test-collection/update -jar post.jar monitor.xml
java -Durl=http://localhost:9090/solr/test-collection/update -jar post.jar mem.xml
제대로 문서들이 Indexing 되었는지를 아래의 요청을 수행해서 확인할 수 있다. (물론 Solr Admin UI 에서도 가능하다)
http://localhost:8080/solr/test-collection/select?q=*:*

구성된 SolrCloud 가용성 테스트

이 정리의 가장 처음에 디자인 했던 테스트 시나리오를 따라서 구성을 했기 때문에 3 개의 Solr Node 들에 균일하게 Shard 가 배포가 되었고, 이들 사이에 복제본들이 존재할 수 있도록 구성되었다. 따라서 좋은 가용성을 보여줄 수 있을 것으로 예상한다. 그러나 이것은 단지 시작을 위한 테스트이기 때문에 실제 고 가용성의 Cluster를 구성하기 위해서는 더 많은 것들을 고려해야 한다. 이제 간단하게 테스트를 해 보도록 하자.
위에서 실행한 조회 요청에 따라서 test-collection 에는 5개의 문서가 존재하는 것을 확인하였다. 이제 제대로 동작하는지 확인하기 위해 Solr Node 1 번을 종료 시키도록 한다.
D:\SolrCloud\web1\bin\shutdown.cmd
Notes
web1 서버 (7070) 가 종료되었기 때문에 ZooKeeper Cluster는 구성된 서버의 문제를 인식하고 바로 Leader 선출과 Replica 상태에 있는 다른 Core를 활성화 시킨다. 처음에 web1 이 Leader 상태고, 다른 서버들이 Replica 상태였지만 아래의 그림과 같이 web2 가 Leader 로 선출되었고, Replica 상태였던 Core 가 활성 상태로 변경된다.
SolrCloud Server1 Down
그리고 동일하게 조회 요청을 시도해 보자. 1번 Node 가 종료되었음에도 불구하고 정상적으로 5건의 문서가 그대로 나오는 것을 확인할 수 있다. 이제 Node 2 번도 종료해 보도록 하자.
D:\SolrCloud\web2\bin\shutdown.cmd
그리고 동일하게 조회 요청을 시도해 보자. 1번과 2번 Node 가 모두 종료되었음에도 불구하고 정상적으로 5건의 문서가 그대로 나오는 것을 확인할 수 있다.
이제 마지막으로 남은 3번 Node 의 Solr Admin UI 를 통해서 Cluster 정보를 확인해 보도록 하자. 아래의 그림과 같이 클러스터 내에 1번과 2번 서버가 종료되었지만 3번 서버에 존재하는 복제 본들이 활성화 되어 Leader 로서 동작하고 있는 것을 확인할 수 있다.
SolrCloud Servers down and Election new Leader
이 상태에서 좀 더 많은 문서들을 3번 서버의 Collection 에 추가를 하면 어떻게 될까? 정상적으로 추가된 문서가 포함된 조회 결과를 얻을 수 있다. 이제 종료한 1번과 2번 서버를 다시 살리고, 1 번이나 2번 서버로 조회 요청을 하면 어떻게 될까?
java -Durl=http://localhost:9090/solr/test-collection/update -jar post.jar ipod_other.xml
위의 명령을 수행하면 2개의 문서를 더 추가해서 총 7개의 문서가 존재하게 된다. 처리 후에 다시 한번 동일하게 web3 를 대상으로 조회를 수행하면 7개의 문서가 제대로 조회 되는 것을 확인할 수 있다.
자, 이번에는 다시 web1 을 살려 보도록 하자. 이 때 web1 이 구동되는 로그를 잘 살펴보면 web1 시작 이후에 “Updating… (live node size:2)” 라는 로그를 볼 수 있다. 즉, ZooKeeper가 web1 이 구동되는 것을 확인해서 현재 활성 상태의 노드가 2 개가 되었다는 것을 인식한 것이다. 아래의 그림과 같이 Solr Admin UI 에서 Cluster를 확인해 보면 web1 이 다시 활성화되었고 Replica 로 동작하는 것을 확인할 수 있다. 단, 이때 Leader는 다시 선출하지 않는다. Leader는 Leader가 장애 상태가 되었을 때만 처리된다.
SolrCloud Server Recovered
이렇게 Node 가 종료 되었다가 다시 실행이 되었고, 그 사이에 문서가 추가되었음에도 누락되는 문서 없이 모두 처리가 되는 이유는 다음과 같은 처리가 내부적으로 SolrCloud 와 ZooKeeper 간의 연동이 되어 운영되기 때문이다.
  • ZooKeeper 는 Cluster 를 구성하는 Node 들을 모니터링 하고 있다가 Node 종료가 발견이 되면 나머지 Node 들에 대해서 Leader 교체에 대한 처리를 수행한다.
  • Leader로 선출된 Node에서는 종료된 Node에 대한 복제본을 활성화 상태로 변경하여 서비스가 계속 진행될 수 있도록 한다.
  • 종료되었던 서버가 다시 구동이 되면 서비스를 대신 했던 Node로 부터 다시 시작된 Node에 해당하는 데이터를 복제하고 복제본으로 동작할 수 있도록 구성한다.
위의 과정은 지금까지 검토하면서 이해한 것을 정리한 내부적인 처리이며, Node 의 종료와 Node 의 시작에 대해서 위의 작업들이 반복적으로 처리되면서 누락이 되지 않는 운영이 가능하다.
테스트를 위한 검토는 여기까지 정리를 하지만 실제 운영에서는 Node를 더 추가하거나 ZooKeeper의 설정을 좀 더 세밀하고 강력하게 설정하는 등의 작업이 추가적으로 필요하게 된다. 그리고 기존에 존재하는 실제 데이터를 SolrCloud 상에 생성한 Collection 에 Import 하는 작업도 처리를 해야 한다.
다음은 SolrCloud 상에서 DIH를 운영하는 방법을 검토해 볼 예정이다.

댓글

이 블로그의 인기 게시물

OData 에 대해서 알아보자.

얼마 전에 어떤 회사에 인터뷰를 하러 간 적이 있었다. 당시 그 회사는 자체 솔루션을 개발할 기술인력을 찾고 있었고 내부적으로 OData를 사용한다고 했다. 좀 창피한 이야기일 수도 있지만 나름 기술적인 부분에서는 많은 정보를 가지고 있다고 했던 것이 무색하게 OData란 단어를 그 회사 사장님에게서 처음 들었다. 작고, 단순한 사이트들만을 계속해서 작업을 하다 보니 어느덧 큰 줄기들을 잃어버린 것을 느끼기 시작했다. 명색이 개발이 좋고, 기술적인 기반을 만들려고 하는 인간이 단어조차도 모른다는 것은 있을 수 없는 것이라서 다시 새로운 단어들과 개념들을 알아보는 시간을 가지려고 한다. OData (Open Data Protocol) 란? 간단히 정리하면 웹 상에서 손쉽게 데이터를 조회하거나 수정할 수 있도록 주고 받는 웹(프로토콜)을 말한다. 서비스 제공자 입장에서는 웹으로 데이터를 제공하는 방식으로 각 포탈 사이트들이 제공하는 OPEN API 포맷을 독자적인 형식이 아니라 오픈된 공통규약으로 제공 가능하며, 개발자는 이 정보를 다양한 언어의 클라이언트 라이브러리로 어플리케이션에서 소비할 수 있도록 사용하면 된다. 공식 사이트는 www.odata.org 이며 많은 언어들을 지원하고 있다. 좀더 상세하게 정의를 해 보면 OData는 Atom Publishing Protocol  (RFC4287) 의 확장 형식이고 REST (REpresentational State Transfer) Protocol 이다. 따라서 웹 브라우저에서 OData 서비스로 노출된 데이터를 볼 수 있다. 그리고 AtomPub 의 확장이라고 했듯이 데이터의 조회만으로 한정되는 것이 아니라 CRUD 작업이 모두 가능하다. Example 웹 브라우저에서 http://services.odata.org/website/odata.svc 를 열어 보도록 하자. This XML file does not appear to have any style in...

C# 에서 Timer 사용할 때 주의할 점.

예전에 알고 지내시던 분의 질문을 받았다. Windows Forms 개발을 하는데, 주기적 (대략 1분)으로 데이터 요청을 하는 프로그램을 작성하기 위해서 Timer 를 사용하는데, 어떤 기능을 처리해야 하기 때문에 Sleep 을 같이 사용했다고 한다. 여기서 발생하는 문제는 Sleep 5초를 주었더니, Timer 까지 5초 동안 멈춘다는 것이다. Timer 라는 것은 기본적으로 시간의 흐름을 측정하는 기능이기 때문에 Sleep 을 했다고 해서 Timer 가 멈추는 일은 생겨서는 안된다. 그러나 실제 샘플을 만들어 보면 ... Timer 가 Sleep 만큼 동작이 멈추는 것을 확인할 수 있다. Windows Forms 는 UI Thread 를 사용하는 것으로 최적화 되어 있으며 여기서 Timer 를 쓰면 UI Thread 에 최적화된 System.Windows.Forms.Timer 가 사용된다. 여기서 문제의 발생이 시작되는 것이다. Sleep 을 사용하게 되면 UI Thread 가 Sleep 이 걸리기 때문에 여기에 속한 Timer 까지도 멈추는 것이다. 이런 문제를 해결하기 위해서는 System.Threading.Timer 를 사용해야 한다. 이 Timer 는 별도의 Thread 에서 동작하기 때문에 Sleep 의 영향을 받지 않는다. 언뜻 보면 쉬운 해결 방법인 것 같지만 Thread 가 분리되었기 때문에 Timer 가 돌아가는 Thread 에서 UI Thread 의 메서드나 컨트롤에 접근하기 위해서는 별도의 명령을 사용해야 하는 문제가 존재한다. 자~ 그럼 여기서 Timer 에 대해서 다시 한번 정리해 보도록 하자. .NET 에서 제공하는 Timer 들 .NET 에서는 기본적으로 3가지 Timer를 제공하고 있다. (MSDN) System.Windows.Forms.Timer - 사용자가 지정한 간격마다 이벤트를 발생시키며 Windows Forms 응용 프로그램에서 사용할 수 있도록 최적화 되어 있다. System...

[Logging] NLog 사용법 정리...

SCSF 에는 기본적으로 Enterprise Library가 사용된다. 예전에도 그랬지만 기능은 훌륭하고 많은 부분에서 최적화(?)된 것일지도 모르지만, 역시나 사용하기에는 뭔가 모르게 무겁고, 사용하지 않는 기능이 더 많다라는 느낌을 지울수가 없다. 이번 프로젝트도 SCSF를 기반으로 하고 있지만, Enterprise Library를 걷어내고 각 부분에 전문화된 오픈 소스를 사용하기로 하였다. 예전에는 Log4Net을 사용했지만, 대량 사용자 환경에서는 메모리 누수와 기타 문제점이 존재한다는 MS 컨설턴트(?)의 전해진 말을 들은 후로는 사용하지 않는다. 대안으로 사용하는 것이 NLog 이다. 조금 후에는 3.0 버전도 나온다고 홈 페이지에 기재되어 있지만, 그 때가 되면 프로젝트는 끝나기 때문에 현재 2.1.0 버전을 사용하기로 했다. [원본 출처] http://cloverink.net/most-useful-nlog-configurations-closed/ 위의 참조 자료에는 다양한 정보들이 존재하므로 꼭 링크를 통해서 관련된 정보를 확인하고 이해하는 것이 좋을 듯 하다. 여기서는 당장 필요한 부분만을 정리하도록 한다. [ Logger 찾기 ] 기본적으로 Logger가 존재하는 클래스를 기반으로 Logger 정보를 구성한다. Logger logger = LogManager.GetCurrentClassLogger(); 주로 Namespace 기반으로 Logger를 설정하는 경우에 유연하게 사용할 수 있다. 또 다른 방법으로는 지정한 문자열로 특정 Logger를 직접 선택하는 방법도 제공된다. 이를 혼용해서 Namespace와 직접 지정 방식을 같이 사용할 수도 있다. 물론 Logger 환경 설정에서 Wildcard (*)를 지정할 수도 있다. Logger logger = LogManager.GetLogger("Database.Connect"); Logger logger = LogManager.Get...