이번에는 Couchbase 를 저장소로 사용하여, Spring Cache 를 사용해 보도록 하겠습니다.
간략하게 Couchbase 에 대해 설명하면... Memcached + CouchDB 라고 보시면 되구요. 설정에 따라 메모리 저장소로 (Memcached), Document DB 형태(CouchDB) 로 사용할 수 있습니다.
Memcached 의 단순 캐시에서 DocumentDB 로 발전했다고 보시면 되고, Map Reduce 도 가능합니다.
하지만!!! 오늘은 그냥 캐시로 사용하려고 합니다.
1. CouchbaseCacheManager
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
@Slf4j | |
public class CouchbaseCacheManager extends AbstractTransactionSupportingCacheManager { | |
private CouchbaseClient couchbaseClient; | |
@Getter | |
@Setter | |
private int expireMillis = 0; // 0 : persist forever | |
public CouchbaseCacheManager(CouchbaseClient couchbaseClient) { | |
this(couchbaseClient, 0); | |
} | |
public CouchbaseCacheManager(CouchbaseClient couchbaseClient, int expireMillis) { | |
Guard.shouldNotBeNull(couchbaseClient, "couchbaseClient"); | |
this.couchbaseClient = couchbaseClient; | |
this.expireMillis = expireMillis; | |
} | |
@Override | |
protected Collection<? extends Cache> loadCaches() { | |
Collection<Cache> caches = Lists.newArrayList(); | |
for (String name : getCacheNames()) { | |
caches.add(new CouchbaseCache(name, couchbaseClient, expireMillis)); | |
} | |
return caches; | |
} | |
@Override | |
public Cache getCache(String name) { | |
synchronized (this) { | |
Cache cache = super.getCache(name); | |
if (cache == null) { | |
cache = new CouchbaseCache(name, couchbaseClient, expireMillis); | |
addCache(cache); | |
} | |
return cache; | |
} | |
} | |
} |
2. CouchbaseCache
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
@Slf4j | |
public class CouchbaseCache implements org.springframework.cache.Cache { | |
@Getter | |
private String name; | |
@Getter | |
private CouchbaseClient nativeCache = null; | |
@Getter | |
@Setter | |
private int expireMillis = 0; // msec (0 is persist forever) | |
public CouchbaseCache(String name, CouchbaseClient client, int expireMillis) { | |
Guard.shouldNotBeNull(name, "name"); | |
Guard.shouldNotBeNull(client, "client"); | |
this.name = name; | |
this.nativeCache = client; | |
this.expireMillis = expireMillis; | |
if (log.isDebugEnabled()) | |
log.debug("CouchbaseCache 를 생성합니다. name=[{}], nativeCache=[{}]", name, nativeCache); | |
} | |
private String getKey(Object key) { | |
return name + "|+|" + key; | |
} | |
@Override | |
public ValueWrapper get(Object key) { | |
Guard.shouldNotBeNull(key, "key"); | |
Object result = nativeCache.get(getKey(key)); | |
SimpleValueWrapper wrapper = null; | |
if (result != null) | |
wrapper = new SimpleValueWrapper(result); | |
return wrapper; | |
} | |
@Override | |
public void put(Object key, Object value) { | |
Guard.shouldNotBeNull(key, "key"); | |
OperationFuture<Boolean> setOp = nativeCache.set(getKey(key), expireMillis, value); | |
if (setOp.getStatus().isSuccess()) { | |
if (log.isDebugEnabled()) | |
log.debug("객체를 캐시 키[{}]로 저장했습니다.", key); | |
} else { | |
if (log.isDebugEnabled()) | |
log.debug("객체를 캐시 키[{}]로 저장하는데 실패했습니다. operation=[{}]", key, setOp); | |
} | |
} | |
@Override | |
public void evict(Object key) { | |
Guard.shouldNotBeNull(key, "key"); | |
if (log.isDebugEnabled()) | |
log.debug("delete cache item... key=[{}]", key); | |
nativeCache.delete(key.toString()); | |
} | |
@Override | |
public void clear() { | |
if (log.isDebugEnabled()) | |
log.debug("clear cache..."); | |
nativeCache.flush(); | |
} | |
} |
3. CouchbaseCacheConfiguration
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
@Configuration | |
@EnableCaching | |
@ComponentScan(basePackageClasses = {UserRepository.class}) | |
@Slf4j | |
public class CouchbaseCacheConfiguration { | |
@Bean | |
public List<URI> couchbaseList() { | |
List<URI> uris = Lists.newArrayList(URI.create("http://localhost:8091/pools")); | |
return uris; | |
} | |
@Bean | |
public CouchbaseClient couchbaseClient() throws IOException { | |
return new CouchbaseClient(couchbaseList(), "default", ""); | |
} | |
@Bean | |
public CouchbaseCacheManager couchbaseCacheManager() throws IOException { | |
return new CouchbaseCacheManager(couchbaseClient()); | |
} | |
} |
환경 설정은 각자 환경에 맞추면 됩니다만, default bucket 만 비밀번호 없이 접근이 가능합니다.
다른 bucket 을 사용하려면, 미리 만드시고, 보안을 설정하셔야 합니다.
4. Couchbase Admin Screenshot
이제 남은 건 Redis 만 남았네요... 요건 다음 기회에...
댓글 없음:
댓글 쓰기