티스토리 뷰

728x90
반응형

 

최근 Hazelcast Client/Server를 이용하여 두 서버의 세션과 캐시를 공유처리 작업을 진행했었습니다.

Hazelcast 방식에는 Embedded 방식과 Client/Server 방식으로 세션 또는 캐시를 관리할 수 있었는데 이 중 좀 더 확장성 있고 독립적으로 존재하여 서버가 가볍게 존재할 수 있는 Client/Server를 적용하였습니다.

그래서 그 과정에 대한 정보들을 정리하려고 합니다.

 

Client/Server를 선택한 이유

Client/Server 모드는 Hazelcast 클러스터와 응용프로그램 즉 Java Application이 분리되어 존재하여 확장성이 좋고 서로 독립적으로 존재한다는 것이 장점이었습니다. 

hazelcast client/server 이해도

위의 사진과 같이 Client/Server 모드를 이용하게 된다면 Cluster인 서버와 Client (Java Application) 부분이 서로 독립적으로 존재한다는 것을 이해할 수 있습니다. 그러면 여기서 확장성이 좋다는 것은 무엇일까요?

 

바로 cluster에 들어가는 Member라는 세션 및 캐시 등을 관리하는 서버를 늘리는데 Emedded 모드보다 수월하다는 것입니다. 왜냐하면 Hazelcast cluster 서버를 추가해야 하는 일이 있을 경우 client App 개수와 상관없이 서로 Multicast 또는 tcp-ip 등을 이용하여 Member 끼리 캐시 또는 세션이 공유가 가능하기 때문입니다.

 

Embedded 같은 경우 ClientApp 즉 Java Application 위의 JVM 에서 같이 돌고 있기 때문에 확장성에 있어서 제한적입니다. client 즉 Java 기준으로 톰켓의 개수를 Cluster 개수를 늘리는 만큼 추가를 해줘야하는 번거러움이 있을 뿐더러 필요없는 메모리 및 서버를 사용하게 되는 일이 발생하게 됩니다. 그래도 Embedded 만의 장점은 존재하긴하지만 오늘은 Client/Server 모드에 대해서만 이야기 하겠습니다 ^^

 

그렇다면 이 이론적인 내용말고 확장성이 좋다는 의미는 과연 어떤것일지 실제 적용을 통해 알아보겠습니다.

 

톰켓 서버 2개를 기준으로 테스트하겠습니다.

1.Member(Hazelcast server) 1개에 client app 2개 일 경우의 문제점

  • 2개의 Client App은 하나의 Cluster (Member)를 바라보고 있어 세션과 캐시를 공유하게 됩니다.
  • 2개의 Client App은 서로 캐시와 세션을 지속적으로 공유하게 됩니다.
  • 그러나 Member가 이슈 또는 어떤 이유로 ShutDown이 될 경우 2개의 Client App은 Member가 다시 살아날때까지 Shutdown 형태가 이루어지게 됩니다.
  • 이렇듯 하나에 의존적인 경우 서버가 다운되게 되면 연결된 client 모두가 문제가 될 수 있습니다.

 

2. Cluster(Member) 개수 추가하기

1번의 문제점들을 Member 확장을 통해 방지할 수 있습니다.

 

  •  JavaApplication에서 우선 client가 접근할 수 있는 member들을 설정합니다. 
  • 개발서버와 로컬서버의 Member에 연결을 설정합니다.
  • hazelcast 서버는 포트번호가 5801과 5802를 가지는 서버가 됩니다.
<hz:client id="instance">
    <hz:instance-name>instance</hz:instance-name>
    <hz:connection-strategy reconnect-mode="ASYNC" async-start="true" >
        <hz:connection-retry enabled="true"  />
    </hz:connection-strategy>
    <hz:group name="cng" password="cng!23" />
    <hz:network connection-timeout="1000"
            redo-operation="true"
            smart-routing="true">
        <hz:member>111.111.0.111:5801</hz:member> <!-- 개발서버 hazelcast-->
        <hz:member>222.222.0.222:5802</hz:member> <!-- 로컬서버 hazelcast-->
    </hz:network>
 </hz:client>

 

 

Hazelcast 연결에는 여러 방법이 있지만 오늘 내용은 Multicast 방식과 Tcp-Ip 방식을 이용해 보겠습니다.

Multicast와 Tcp-Ip는 서로 다른 Member사이의 연결을 해주는 방식으로 서로간의 캐시와 세션을 공유하도록 해주는 역할을 합니다. 만약 이러한 설정이 안되어있을경우 Cluster(Member)를 아무리 늘려봤자 각자 돌아가는 서버가 되어 데이터의 일관성을 제공하지 못하게 됩니다.

 

3. MultiCast를 이용한 Member들 연동하기

  • hazelcast.xml
<network>
		<rest-api enabled="true">
            <endpoint-group name="HEALTH_CHECK" enabled="true"/>
        </rest-api>
        <port auto-increment="true" port-count="100">5802</port>
        <outbound-ports>
            <!--
            Allowed port range when connecting to other nodes.
            0 or * means use system provided port.
            -->
            <ports>0</ports>
        </outbound-ports>
        <join>
            <multicast enabled="true">
                <multicast-group>224.2.2.3</multicast-group>
                <multicast-port>54327</multicast-port>
            </multicast>
            <!--<tcp-ip enabled="false">
                <interface>127.0.0.1</interface>
                <member-list>
                    <member>127.0.0.1</member>
                </member-list>
            </tcp-ip>-->
				    ...
				</join>
</network>

 

  • hazelcast.xml에서 Multicast 부분을 true로 변경하면 됩니다.
  • 기본적으로 Multicast는 224.x.x.x 로 시작되도록 정해져있습니다.
  • Multicast가 개발서버와 로컬서버가 설정되어 있다면 hazelcast 실행하였을시 아래와 같은 로그가 뜨게 됩니다.

 

개발서버에서 hazelcast log를 보게 되면 아래와 같이 this라고 표시된 부부인 현재 할당받고 있는 멤버를 의미하게 됩니다.

Members {size:2, ver:8} [
        Member [111.111.0.111]:5801 - 9b9cb740-6a28-46cf-ac65-4c26a716163e this
        Member [222.222.0.222]:5802 - 6bc1ac43-8811-4485-a68a-bcd0470633a8
]

 

반대로 로컬에서 hazelcast log를 살펴보게 되면 아래와 같은 this를 가지게 됩니다.

Members {size:2, ver:8} [
        Member [111.111.0.111]:5801 - 9b9cb740-6a28-46cf-ac65-4c26a716163e 
        Member [222.222.0.222]:5802 - 6bc1ac43-8811-4485-a68a-bcd0470633a8 this
]

 

그렇다면 Client App을 실행하였을시 어떤 내용이 있는지 확인해보겠습니다.

Members [2] {
	Member [111.111.0.111]:5801 - 9b9cb740-6a28-46cf-ac65-4c26a716163e 
        Member [222.222.0.222]:5802 - 6bc1ac43-8811-4485-a68a-bcd0470633a8
}

 

이렇게 Client App에는 hazelcast log와 동일하게 Member가 할당이 됩니다. 하지만 어느 멤버를 할당 받는지는 랜덤으로 할당받게 됩니다.

 

hazelcast-mancenter 에서 cluster 확인

  • 현재 Member는 2개가 올라가 있는것을 확인할 수 있습니다.

Member와 Client 입니다.

member와 client 정보

이렇게 될경우 Hazelcast 서버 하나가 만약 문제가 발생하였을 경우 다른 한쪽 서버가 이상이 없다면 모든 Client App은 살아있게 됩니다.

 

그렇다면 직접 한쪽 Member를 강제 Shutdown 하는 예제를 보겠습니다.

예시) 개발서버를 shutdown 했을 경우

 

→ ./stop.sh 서버 다운

Members [2] {
	Member [222.222.0.222]:5802 - 6b411810-4558-4e93-a4d6-7bba14a89080
	Member [111.111.0.111]:5801 - ed9c09e2-446d-40ce-82d9-3c513158194d
}

....

Members [1] {
	Member [222.222.0.222]:5802 - 6b411810-4558-4e93-a4d6-7bba14a89080
}

 

Member 하나가 서버가 다운되는 상황이 발생하였을 경우 Client App은 남아있는 나머지 Member를 할당 받게 됩니다. Member는 서로 Multicast를 통해 캐싱과 세션을 공유하고 있기 때문에 실제 사용자들은 사용에 있어서 문제가 없게 됩니다.

 

 

다시 개발서버를 start 했을 경우

→ ./start.sh

Members [1] {
	Member [222.222.0.222]:5802 - 6b411810-4558-4e93-a4d6-7bba14a89080
}

2월 28, 2024 1:56:41 오후 com.hazelcast.client.spi.impl.ClientMembershipListener
정보: instance [cng] [3.12.13] 

Members [2] {
	Member [222.222.0.222]:5802 - 6b411810-4558-4e93-a4d6-7bba14a89080
	Member [111.111.0.111]:5801 - 7d0fb7d0-83e8-44e9-9021-2af971077b50
}

 

다시 새롭게 Member가 올라오게되어 다시 새팅하는 것을 확인할 수 있습니다.

 

만약 내가 원하는 Member들끼리만 공유를 하고 싶을 경우는 어떻게 하면 좋을까요?

 

4.hazelcast.xml multicast 에서 특정 ip만 공유되도록 설정하기

 <join>
    <multicast enabled="true">
        <multicast-group>224.2.2.3</multicast-group>
        <multicast-port>54327</multicast-port>
                        <trusted-interfaces>
                                <interface>111.111.0.111</interface>
                                <interface>222.222.0.222</interface>
                        </trusted-interfaces>
    </multicast>
    
    ...
</join>

 

trusted-interfaces 를 설정하게되면 특정 ip 한에서 Member를 Multicast하게 됩니다.

만약 trusted-interfaces를 설정하지 않는경우 모든 Member가 Multicast가 됩니다.

 

만약 333.333.0.333 ip를 가지는 hazelcast Member가 있다면 해당 Member는 위와 같이 설정되어있는 경우

222.222.0.222와 111.111.0.111과 Multicast가 되지 않습니다.

 

5. 막간으로 Tcp-Ip를 이용한 Member 확장하기

  • hazelcast.xml

→ tcp-ip의 enabled 값을 true로 바꾸고 나서 사용하는 cluster의 Member들의 ip를 지정해주면 됩니다.

<join>
    <multicast enabled="false">
         <multicast-group>224.2.2.3</multicast-group>
         <multicast-port>54327</multicast-port>
		   	 <trusted-interfaces>
              <interface>111.111.0.111</interface>
				      <interface>222.222.0.222</interface>
         </trusted-interfaces>
    </multicast>
    <tcp-ip enabled="true">
		<member-list>
         	//tcp-ip를 통해 서로 공유하고자 하는 Member를 선언
			<member>111.111.0.111</member>
			<member>222.222.0.222</member>
        </member-list>
     </tcp-ip>
</join>

 

 

 

만약 Member 서버가 모두 끊길 경우는??
2월 28, 2024 4:16:21 오후 com.hazelcast.client.connection.nio.ClusterConnectorService
경고: instance [cng] [3.12.13] Exception during initial connection to [222.222.0.222]:5802: com.hazelcast.core.HazelcastException: java.net.SocketTimeoutException
2월 28, 2024 4:16:21 오후 com.hazelcast.client.connection.nio.ClusterConnectorService
정보: instance [cng] [3.12.13] Trying to connect to [111.111.0.111]:5801 as owner member
2월 28, 2024 4:16:22 오후 com.hazelcast.client.connection.nio.ClusterConnectorService
경고: instance [cng] [3.12.13] Exception during initial connection to [111.111.0.111]:5801: com.hazelcast.core.HazelcastException: java.net.SocketTimeoutException
2월 28, 2024 4:16:22 오후 com.hazelcast.client.connection.nio.ClusterConnectorService
경고: instance [cng] [3.12.13] Unable to get live cluster connection, retry in 949 ms, attempt 1, retry timeout millis 30000 cap

 

지속적으로 다시 Client App들은 Cluster(Member)에 연결을 재시도하게 됩니다. 하지만 여러번의 시도에도 안될 경우 Client App 또한 서버가 닫히게 됩니다. ㅜㅜㅜ

 

 

이상 ~ Hazelcast Client/Server Cluster Member를 추가하는 방법에 대하여 정리하였습니다~

 

728x90
반응형
250x250
반응형
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2025/01   »
1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31
글 보관함