HA 기능 관련 R&D 했던 것을 정리해본다.
기능보다 구현 관련해서 생각했던 점을 merge 하기 위해 써본다.
1. Active-Active 환경이다.
2. Heap 메모리에 데이터를 넣지 않고, 저장소도 경우 및 공유하지 않는 상태에서 통신을 할 것이다.
3. Instance 정보를 동기화하기 위한 목적으로 H/A 기능이 필요하다.
4. Redis, Kafka를 쓰지 않는다.
5. 언어는 Java, Spring Boot 를 쓴다.
6. 별도로 프로세스를 띄우지 않고, 기본적인 환경에서 동작할 수 있도록 한다.
7. 따라서 ZooKeeper를 사용하지 않는 방향으로 진행한다. (따로 인스턴스 띄우지 않기 위해서 미사용한다.)
Summary : Cloud 기능이나 Database 기능이 없이, 서로 통신해서 인스턴스의 local 상태를 공유하는 기능을 만들 것이다.
확장성을 고려하여, active-active 환경에서 인스턴스 정보를 동기화하는 방법으로는 여러가지가 있습니다. 하지만, 데이터를 heap memory에 저장하지 않고, 중간 저장소 없이 통신하는 것이 요구사항이기 때문에, 아래와 같은 방법을 추천해드립니다.
Hazelcast 사용
Hazelcast는 자바 기반의 인-메모리 데이터 그리드 기술을 제공하는 오픈소스 프로젝트입니다. Hazelcast를 사용하면 서로 다른 노드 간에 데이터를 공유할 수 있습니다. Hazelcast는 클러스터링, 분산 맵, 분산 큐 등 다양한 기능을 제공하며, 다수의 클라이언트가 동시에 접속할 수 있습니다.
JGroups 사용
JGroups는 멀티캐스팅과 유니캐스팅을 사용하여 자바 애플리케이션에서 클러스터를 구성할 수 있는 오픈소스 라이브러리입니다. JGroups를 사용하면 서로 다른 노드 간에 메시지를 보내고 받을 수 있으며, 확장성이 높은 클러스터링 기능을 제공합니다.
RMI(Remote Method Invocation) 사용
RMI는 자바 애플리케이션 간에 객체를 공유하고 메소드를 호출하는 기술입니다. RMI를 사용하여 서로 다른 노드 간에 인스턴스 정보를 공유하고 동기화할 수 있습니다. RMI를 사용하면 자바 객체를 직렬화하여 전송할 수 있으므로, 객체의 크기나 복잡도에 제한이 없습니다.
위의 방법들 중 Hazelcast를 추천드리며, Hazelcast를 사용하여 노드 간에 데이터를 공유하면, 중간 저장소 없이도 인스턴스 정보를 동기화할 수 있습니다. 또한, Hazelcast는 클러스터링, 분산 맵, 분산 큐 등 다양한 기능을 제공하며, 확장성이 뛰어나므로, 대규모 애플리케이션에서도 사용할 수 있습니다.
리서치 후에 Chatgpt에게 물어봐도 Hazelcast 를 추천하기에, 이걸로 진행 해보려고 한다.
위 요구사항에 따라 구현할 수 있는 방법 중 하나는 분산 캐시 라이브러리인 Hazelcast를 사용하는 것입니다.
Hazelcast는 분산 캐시 기능뿐만 아니라 분산 데이터 구조, 메시징, 이벤트 등 다양한 기능을 제공합니다. Active-Active 환경에서는 Hazelcast를 사용하여 각 인스턴스의 로컬 상태를 공유하고 동기화할 수 있습니다.
Hazelcast를 Spring Boot 프로젝트에 적용하는 방법은 다음과 같습니다.
1. 의존성 추가
build.gradle 파일에 다음과 같이 의존성을 추가합니다.
```gradle
implementation 'com.hazelcast:hazelcast-spring:4.1.3'
```
2. Hazelcast 설정
application.properties 파일에 다음과 같이 Hazelcast 설정을 추가합니다.
```properties
# Hazelcast 설정
hazelcast:
instance-name: my-hazelcast-instance
network:
join:
multicast:
enabled: false
tcp-ip:
enabled: true
members: 127.0.0.1:5701, 127.0.0.1:5702
```
위 설정에서는 인스턴스 이름과 멤버 목록을 설정하였습니다.
3. Hazelcast 캐시 사용
Hazelcast 캐시를 사용하기 위해 Spring Cache Abstraction을 적용하고, `@Cacheable` 어노테이션을 사용하여 캐시를 적용합니다.
```java
@Configuration
@EnableCaching
public class CacheConfig extends CachingConfigurerSupport {
@Bean
public HazelcastInstance hazelcastInstance() {
Config config = new Config();
config.setInstanceName("my-hazelcast-instance");
config.getNetworkConfig().getJoin().getTcpIpConfig().setEnabled(true)
.addMember("127.0.0.1:5701").addMember("127.0.0.1:5702");
return Hazelcast.newHazelcastInstance(config);
}
@Bean
@Override
public CacheManager cacheManager() {
return new HazelcastCacheManager(hazelcastInstance());
}
}
@Service
public class MyService {
@Cacheable("my-cache")
public Object get(String key) {
// ...
}
}
```
위 예제에서는 `@Cacheable` 어노테이션을 사용하여 `my-cache` 캐시를 적용하였습니다.
이와 같이 Hazelcast를 사용하여 Active-Active 환경에서 인스턴스 정보를 동기화하고 로컬 상태를 공유할 수 있습니다.
근데 Hazelcast도 성능 다 열어놓고 쓰려면 라이선스 문제가 좀 있어서 default만 사용하는 조건으로만 개발해서 도입할 만 한 것 같다.
참조 :
사실 getConfig 하는 쪽 찾다가 A-A 상태로 개발하신 분 블로그 찾은 것이 많이 도움이 되었다.
댓글
댓글 쓰기