Redis(In-Memory DB)를 사용해서 속도를 끌어올리자

황씨·2024년 7월 17일
post-thumbnail

웹/앱을 다하고 있지만 하드웨어 관련된 프로그램을 개발하는건 역시 손도 많이가고 신경써야할 부분이 너무 많은 것 같다

우선 원래 구현 해놓은 것은

단말기 태깅 -> 태깅 데이터 우리서버에서 가공 -> 가공한데이터를 다른 서버로 전송

해당 로직으로 구현을 해놓았다.

그런데 한번에 많은 사람들이 태깅을 하다보니 통신에 문제인가? 속도의 문제인가?
정확한 원인은 알 수 없지만 TimeOut 이 나는 것으로 보인다.

태깅하면 탑승자의 정보를 MYSQL에다가 정보를 담고 있었는데,

MYSQL에 관련된 로직은 다 빼고 Redis로 처리를 하고,
나중에 Redis에 있는 탑승자 정보를 스케줄러를 통해서 MYSQL로 데이터를 옮길려고 한다.

Redis 를 쓰면 속도가 올라가서 타임아웃에러가 안나길 바라면서 진행하였다..
많은 자료구조로 넣을 수 있지만 Key-Value 값으로 처리하면 속도가 가장 빠르다고 하던데,
데이터 타입마다 다를 것 같긴하다. 어쨋든 key-Value 형식으로 진행!

간단하게 보면 key 값을 이용해 value(데이터)를 조회한다.

set key1 "HelloWorld" 

로 넣으면 ,

get key1
-> "HelloWorld"

로 조회한다.

spring 프로젝트(gradle)였기에

📌 우선 Redis 세팅을 위해서 build.gradle 에다가 추가

implementation 'org.springframework.boot:spring-boot-starter-data-redis'

📌 그리고 Config 파일을 만들어서 설정값을 작성한다.

Configuration
public class RedisConfig {
	
	@Bean
    public RedisConnectionFactory redisConnectionFactory() {
        return new LettuceConnectionFactory("내 서버 IP", 6379);
    }
	
	@Bean
	public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory connectionFactory){
		RedisTemplate<String, Object> template = new RedisTemplate<>();
		template.setConnectionFactory(connectionFactory);
		template.setKeySerializer(new StringRedisSerializer());
		template.setValueSerializer(new GenericJackson2JsonRedisSerializer());
	    template.setHashKeySerializer(new StringRedisSerializer());
        template.setHashValueSerializer(new GenericJackson2JsonRedisSerializer());
        return template;
	}
}

(참고로 properties에 ip랑 port번호를 넣었는데 접근이 안되서
LettuceConnectionFactory로 해결했다..)

자 이제 Redis 세팅 끝.

📌 이제 서비스단 만들어서 구현을 시작하면 된다.

@Service
public class RedisService {

	@Autowired
	private StringRedisTemplate redisTemplate;
	
	private final ObjectMapper objectMapper = new ObjectMapper();
	
	public Map<String, Object> getBusDeviceInfo(String deviceID){
		String key = "busDeviceInfo:" + deviceID;
		String data = redisTemplate.opsForValue().get(key);
		
		if(data != null) {
			try {
				return objectMapper.readValue(data, Map.class);
			}catch (Exception e) {
				e.printStackTrace();
			}
		}
		return null;
	}
	
	public void cacheBusDeviceInfo(String deviceId, Map<String, Object> deviceInfo) {
		String key = "busDeviceInfo:" + deviceId;
		try {
			redisTemplate.opsForValue().set(key, objectMapper.writeValueAsString(deviceInfo));
		} catch(Exception e) {
			e.printStackTrace();
		}
	}
	
	public String getRouteIdentificationNumber(String deviceID) {
		Map<String, Object> deviceInfo = getBusDeviceInfo(deviceID);
		if(deviceInfo == null) {
			return null;
		}
		
		int areaCode = Integer.parseInt(deviceInfo.get("area_code").toString());
		String currentTime = LocalTime.now().format(DateTimeFormatter.ofPattern("HHmm"));
		
		if(areaCode == 1 && currentTime.compareTo("0000") >= 0 && currentTime.compareTo("1159") <= 0) {
			return "ChangwonBundang";
		} else if(areaCode == 1 && currentTime.compareTo("1159") > 0) {
			return "BundangChangwon";
		} else if(areaCode == 2 && currentTime.compareTo("0000") >= 0 && currentTime.compareTo("1159") <=0) {
			return "BundangChangwon";
		} else if(areaCode == 2 && currentTime.compareTo("1159") > 0) {
			return "ChangwonBundang";
		}
		
		return null;
	}
	
	public Map<String, Object> getBusInfo(int biCode) {
		String key = "busCode:" + biCode;
		String data = redisTemplate.opsForValue().get(key);
		
		if(data != null) {
			try {
				return objectMapper.readValue(data, Map.class);
			}catch (Exception e) {
				e.printStackTrace();
			}
		}
		return null;
	}
	
	public void insertPassengerInfo(Map<String, Object> passengerInfo) {
		String key = "busPassengerInfo:" + passengerInfo.get("employeeId") + ":" + passengerInfo.get("tagDt");
		try {
			redisTemplate.opsForValue().set(key,objectMapper.writeValueAsString(passengerInfo));
		}catch(Exception e) {
			e.printStackTrace();
		}
	}
}

간단하게 보면 select와 insert가 있는데
단말기ID(deviceID)가 키값이 되기에,

busDeviceInfo:"단말기에서 넘겨받은 ID값" (key 값)으로
data를 조회한다.

그리고 insert부분은 insertPassengerInfo가 되는데
컨트롤러단에서 받아온 값을 파라미터로 넘겨받아서
busPassengerInfo:"파라미터로 받은 값"(key)값을 이용해서 데이터를 insert 시킨다.

후에 Redis에 이런식으로 처리를하여 가공한 데이터를 외부 서버로 보내었다.

처음해본 Redis 였는데, 서버에 메모리를 사용하여 데이터 처리를 한다는게 좀 신기했던 것 같고
속도가 빨라진게 확실히 느껴지긴했다(아주많이,,).

간단한 데이터를 담고 빼고 빠른속도가 필요할 땐 쓸모가 많을 거 같은 녀석인 것 같다.
(세션같은거?)

그래도 하드웨어가 첨가된 개발은 좀,, 손이 많이 간다..

profile
성격존나급한 개발자

1개의 댓글

comment-user-thumbnail
2024년 7월 25일

하드웨어 첨가된 개발을 하고 있는 당신은 똑쟁이?

답글 달기