Skip to content

Commit c0269a3

Browse files
fix : 공연 제목 자동 검색 저장시 배치 사이즈를 나누어 저장하여 데이터 유실 방지
1 parent d40e095 commit c0269a3

1 file changed

Lines changed: 29 additions & 19 deletions

File tree

src/main/java/com/back/web7_9_codecrete_be/domain/concerts/repository/ConcertSearchRedisTemplate.java

Lines changed: 29 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -25,29 +25,39 @@ public class ConcertSearchRedisTemplate {
2525

2626
public void addAllWordsWithWeight(List<WeightedString> weightedStrings) {
2727
// PipeLine 사용해서 한번에 처리 -> IO 시간 감소
28-
redisTemplate.executePipelined((RedisCallback<?>) connection ->{
29-
for (WeightedString weightedString : weightedStrings) {
30-
String id = String.valueOf(weightedString.getConcertId());
31-
String word = weightedString.getWord();
32-
double score = weightedString.getScore();
28+
// 대량의 파이프라인 작업시 Zset 양이 너무 많으면 set 처리가 누락되는 문제 발생 -> 한번에 batch X, 여러번 나누어서 처리
29+
int batchSize = 50;
30+
for(int i = 0; i < weightedStrings.size(); i+=batchSize) {
31+
List<WeightedString> batch = weightedStrings.subList(i, Math.min(i + batchSize, weightedStrings.size()));
32+
redisTemplate.executePipelined((RedisCallback<?>) connection ->{
33+
for (WeightedString weightedString : batch) {
34+
String id = String.valueOf(weightedString.getConcertId());
35+
String word = weightedString.getWord();
36+
double score = weightedString.getScore();
3337

34-
// 검색 결과를 ID - 제목 쌍으로 저장
35-
connection.commands().set((CONCERT_ID_KEY + id).getBytes(StandardCharsets.UTF_8),word.getBytes(StandardCharsets.UTF_8));
38+
// 직렬화 도구 명시적 사용 (Template 설정과 일치)
39+
byte[] key = redisTemplate.getStringSerializer().serialize(CONCERT_ID_KEY + id);
40+
byte[] value = redisTemplate.getStringSerializer().serialize(word);
41+
byte[] idByte = redisTemplate.getStringSerializer().serialize(id);
3642

37-
// 역 인덱싱
38-
for(int i = 0 ;i<word.length();i++){
39-
for(int j = i+1;j<= word.length();j++ ){
40-
String subWord = word.substring(i,j);
41-
// 공백은 검색어 인덱스에서 제외
42-
if(subWord.isBlank()) continue;
43-
// 서브 문자열을 인덱스 키, 값은 ID 값으로 해서 저장
44-
byte[] indexKey = (INDEX_KEY + subWord).getBytes(StandardCharsets.UTF_8);
45-
connection.zAdd(indexKey,score,id.getBytes(StandardCharsets.UTF_8));
43+
// 검색 결과를 ID - 제목 쌍으로 저장
44+
connection.commands().set(key,value);
45+
46+
// 역 인덱싱
47+
for(int k = 0 ;k<word.length();k++){
48+
for(int j = k+1;j<= word.length();j++ ){
49+
String subWord = word.substring(k,j);
50+
// 공백은 검색어 인덱스에서 제외
51+
if(subWord.isBlank()) continue;
52+
// 서브 문자열을 인덱스 키, 값은 ID 값으로 해서 저장
53+
byte[] indexKey = redisTemplate.getStringSerializer().serialize(INDEX_KEY + subWord);
54+
connection.zAdd(indexKey, score, idByte);
55+
}
4656
}
4757
}
48-
}
49-
return null;
50-
});
58+
return null;
59+
});
60+
}
5161
}
5262

5363
public List<AutoCompleteItem> getAutoCompleteWord(String keyword, int start, int end) {

0 commit comments

Comments
 (0)