목록전체 글 (88)
생각해보기
DB 와 I/O 데이터베이스의 성능 튜닝은 어떻게 디스크 I/O를 줄이느냐가 관건일 때가 많다. 쿼리 튜닝은 꼭 필요한 데이터만 읽도록, I/O를 줄이는 방향으로 쿼리를 개선하는 것을 의미한다. SSD는 디스크 원판을 기계적으로 회전할 필요가 없어 HDD 보다 빠르게 읽고 쓸 수있다. SSD는 순차 I/O 도 HDD보다 빠르지만 랜덤 I/O에서 훨씬 빠르다. 성능 옵션에서 SSD도 고려해 보자. (SSD 초당 436, HDD 초당 60개 트랜잭션 처리) 디스크의 성능은 얼마나 많은 데이터를 한 번에 기록하느냐에 결정 될 수 있다. 따라서 빈번하게 읽고 쓰는 랜덤 I/O 보다, 순차 I/O가 빠르다. 인덱스 DBMS에서 인덱스는 데이터의 저장성능을 희생하고(일관성 정렬을 유지해야하기 때문에) 그 대신 데이..
Mysql의 잠금이 무엇이 있는지 확인해보고 싶었습니다. Mysql에서 사용되는 잠금은 크게 스토리지 엔진 레벨과 Mysql 엔진 레벨로 나눌 수 있습니다. Mysql 엔진 레벨의 잠금은 모든 스토리지 엔진에 영향을 미치지만, 스토리지 엔진 레벨의 잠금은 스토리지 엔진 간에 영향을 미치지 않습니다. Mysql 엔진 레벨의 잠금은 다음과 같습니다. 글로벌 락 Mysql에서 제공하는 락 중에 가장 범위가 큽니다. 한 세션 에서 글로벌 락을 획득하면 다른 세션에서는 조회를 제외하고 락이 해제 될 때 까지 대기 해야 합니다. 테이블 락 개별 테이블 단위로 설정되는 락입니다. 스키마를 변경하는 DDL의 경우 테이블 락이 설정됩니다 네임드 락 임의의 문자열에 대해 잠금을 설정할 수 있습니다. 여러 서버를 동기화 해..
mysql의 서버는 크게 mysql 엔진과 스토리지 엔진으로 구분할 수 있습니다. mysql 엔진의 역할 사람으로 치면 머리에 해당하는 역할입니다. 쿼리를 파싱하고 쿼리를 최적화 하여 sql을 실행합니다. 스토리지 엔진의 역할 사람으로 치면 손과 발에 해당하는 역할입니다. mysql 엔진이 커넥터를 통해 스토리지 엔진에게 데이터 읽기/쓰기 명령을 보냅니다. 스토리지 엔진은 해당 명령을 수행합니다. 대표적인 스토리지 엔진은 InnoDB가 존재합니다 MySQL의 특징 중에 대표적인 것은 플러그인 모델입니다. 각각의 기능들을 플러그인 형태고 개발해서 사용할 수 있습니다. 따라서 사용자는 기본적인 기능 이외에도 부가적인 기능을 위해서 직접 개발을 할 수 도 있습니다. 대표적으로 스토리지 엔진에서는 InnoDB,..
jpa에서 쿼리 등록이 어떻게 되고, 어떻게 관리되는 지 궁금했습니다. jpa 내부를 살펴보겠습니다. JpaRepository가 호출될때 jdkDyamicAopProxy를 통해서 여러개의 interceptor를 체인 형태로 호출하게 됩니다. 체인 형태로 호출 할때 ReflectiveMethodInvocation을 사용합니다. // ReflectiveMethodInvocation @Override @Nullable public Object proceed() throws Throwable { // We start with an index of -1 and increment early. // 사용되는 interceptor는 순차적으로 interceptorsAndDynamicMethodMatchers에 등록됩니..
서블릿과 필터는 Java EE(enterprise edition)을 스펙을 기반으로 합니다. 기존의 filter를 등록하는 표준 방식(ex. web.xml 설정)에서는 서블릿 컨테이너에 의해 직접 관리됩니다. 따라서 서블릿 컨테이너가 직접 관리하는 필터는 스프링 애플리케이션 컨텍스트 내에서 정의하는 빈들을 인식하지 못합니다. 따라서DelegatingFilterProxy를 통해 스프링 빈으로 요청을 위임합니다. DelegatingFilterProxy는 FilterProxy(FilterChainProxy)구현체를 찾아 위임합니다. // DelegatingFilterProxy.java @Override public void doFilter(ServletRequest request, ServletResponse..
conda 와 virtual env에서 requirement.txt를 추출하다 보니, 이전에 실험용으로 다운 받은 의존성도 실수로 같이 받아져서, requirement.txt 가 커지고 빌드 시간이 나는 문제가 있었습니다. 또한 더 좋은 편의성을 갖추고 싶었습니다. 편의성 측면에서 원했던 것은 크게 2가지 였습니다. 첫번째는 모듈을 받을 때 어떤 모듈에 의존성을 가지는지 궁금했고, 의존성 트리를 보고 싶었습니다. 두번째는 test와 dev, local 등으로 group을 나누어 의존성을 관리하면 의존성을 보기 쉽고 안전하게 만들고 싶었습니다. 이러한 이유로 poetry를 도입하게 되었고, poetry에 대해서 간략한 설명과 어떻게 사용되고 있는지 공유하겠습니다. poetry란? poetry는 파이썬 의존..
스프링 프레임 워크를 공부하면서, 서블릿, 서블릿 컨테이너, 서블릿 컨텍스트 등에 궁금해졌습니다. 각각의 용어를 정리하고, 스프링 부트가 어떻게 실행 되는지 확인을 해보고자 합니다. 서블릿 (Servlet): Java에서 HTTP 요청을 처리하기 위해 사용되는 Java 클래스입니다. HTTP GET, POST, PUT, DELETE 등의 요청을 처리할 수 있습니다. 웹 페이지의 동적 콘텐츠 생성을 위해 사용됩니다. 서블릿 컨텍스트 (ServletContext): 웹 애플리케이션의 전체 범위에 걸쳐 공유되는 정보를 저장하는 객체입니다. 웹 애플리케이션의 전체 생명 주기 동안 유지되며, 모든 서블릿과 JSP는 동일한 ServletContext 객체를 공유합니다. 서블릿 간의 데이터 공유, 애플리케이션 수준의..
현재 회사에서 기존의 레거시를 python fastapi로 전환하는 작업을 진행하고 있습니다. fastapi에서 depency injection(DI)가 spring framework 만큼 편리하지 않았기에, spring boot는 어떻게 DI를 진행하는지 궁금하게 되었습니다. spring boot에서는 주로 @Autowire 어노테이션을 사용하여 DI 진행합니다. @Autowire을 사용하여 주입하는 bean을 주입하는 방식은 대표적으로 3가지가 있습니다 1. 생성자 주입 생성자가 호출되는 시점에 주입이 이루어집니다. 생성자를 통한 주입은 객체가 생성되는 시점에 모든 의존성이 주입되므로, 이후에는 해당 의존성이 변경되지 않는 불변성을 보장합니다. @Service public class MyService..
스프링에서 간단히 @Transactional을 적는 것으로, 쉽게 트랜잭션을 구현할 수 있습니다. 어떻게 이 과정이 수행되는지 궁금했고 코드를 보면서 분석을 해보았습니다. 우선 @Transactional 어노테이션은 AOP 기능을 기반으로 동작을 합니다. Spring에서 AOP는 두가지 방법으로 구현을 합니다. AOP에 대한 자세한 내용은 해당 포스트에 좋은 글이 있어 공유 합니다. ( https://steady-coding.tistory.com/608 ) AOP란? 더보기 AOP는 이러한 교차 관심사를 분리하여 별도의 모듈로 만들고, 이를 필요한 시점에 적용하도록 합니다. 이렇게 함으로써 기능별로 코드를 분리하고 재사용성을 높이며, 유지 보수성을 향상시킬 수 있습니다. AOP(Aspect-Oriente..
데이터베이스 인덱스는 데이터베이스 테이블의 데이터를 더 빠르게 검색하고 쿼리하는 데 사용되는 자료구조입니다. 책의 색인과 비슷합니다. 데이터베이스에서 특정 값을 찾고자 할 때, 테이블의 모든 행을 검사하지 않고 해당 값이 있는 행을 빠르게 찾을 수 있게 해줍니다. 인덱스를 사용하면 데이터 검색 속도가 빨라 지지만 테이블에 데이터를 삽입하거나, 업데이트 하는 작업은 더 오래 걸릴 수 있습니다. 왜냐하면 각 삽입이나 업데이트 시 변경에 대해서 인덱스 역시 업데이트를 해야 하기 때문입니다. 따라서, 성능 튜닝에 좋은 도구 이지만, 어떤 열에 인덱스를 생성할지, 어떤 타입의 인덱스를 사용할지 등은 확인후에 결정해야 합니다. 그렇다면 인덱스를 걸기에 효율적인 칼럼은 무엇일까요? 읽기 작업이 쓰기 작업에 비해 많고..
스프링에서는 요청에 매칭되는 다양한 매개변수 들이 있습니다. 대표적으로 다음과 같은 매개변수가 존재합니다. @RequestParam: 클라이언트로부터 전송된 파라미터 값을 Handler(Method)의 파라미터로 사용할 수 있게 매핑해주는 어노테이션입니다. 예를 들어, GET 방식의 요청에 ?name=example이라는 쿼리 문자열이 있다면, @RequestParam("name") String name으로 해당 값을 받을 수 있습니다. 필수 여부를 설정할 수 있으며, 기본값은 true입니다. 필수가 아닌 경우 @RequestParam(required = false)를 사용할 수 있습니다. @RequestBody: 클라이언트로부터 전송된 JSON 혹은 XML 등의 데이터를 Java Object로 변환해서 ..
웹 브라우저와 웹 서버간이 통신 프로세스는 여러 단계로 나뉩니다. 브라우저가 웹 페이지를 요청하면, 그 요청은 DNS 부터 시작해서 최종적으로 요청, 응답까지 도달 합니다. 웹의 통신 흐름의 각 요소를 살펴보겠습니다. 1. 사용자의 브라우저 입력 사용자의 요청을 브라우저에서 검증하여 유효한지 확인하는 단계입니다. 입력된 URL을 분석하여 여러 요소를 파악합니다. URL 문법 scheme://[userinfo@]host[:port][/path][?query][#fragment] ex) https://www.google.com:443/search?q=hello&hl=ko • scheme : 프로토콜을 명시합니다 • urderinfo : url에 사용자 정보를 포함해서 인증합니다. 거의 사용하지 않습니다 • ..
Java는 처음 부터 다중 스레드 환경을 지원하도록 설계되었습니다. 자바에서 가장 처음 동시성을 제어하기 위해 사용된 구조는 가본적인 ‘synchronized’ 키워드와 wait-notify 메커니즘입니다. 추후에 복잡한 동시성을 제어하기 위해 더 많은 기능들이 생겨났습니다. 주요한 동시성 요소를 가볍게 살펴보고, synchronized의 lock 범위를 중점적으로 설명하겠습니다. (이후의 내용은 추후에 다루겠습니다) java 주요 동시성 요소 스레드 등장 : java 1.0 java의 기본적은 동시성 단위입니다. 쓰레드는 프로세스 내에서 실행되는 독립적인 실행 경로입니다. 각 스레드는 자신만의 스택을 가지지만, 힙 메모리는 공유됩니다. 스레드는 java.lang.Thread 클래스나 java.lang...
예전에 JVM에 동작방식에 대해 공부를 했지만. 잘 기억이 나질 않았습니다. 이번에 다시 공부하면서, 관련된 내용을 요약 및 정리를 했습니다. JVM의 동작 방식, 메모리 구조 부터, 변경 사항을 정리한 글입니다. JVM 동작 방식 자바 컴파일러(javac)가 자바 소스코드(.java)를 바이트코드(.class)로 컴파일 합니다. 클래스 로드를 통해서 다음과 같은 과정을 거칩니다 로딩 : 클래스를 읽어오는 과정 .class 파일을 가져와서 jvm의 메서드 영역에 배치합니다. 이 영역에는 코드, 메타 데이터, static 변수등이 포함되어 있습니다. 링크 : 레퍼런스를 읽는 과정 검증, 준비, 해석의 세부 단계로 나뉩니다 검증 : 바이트 코드가 안전한지 확인합니다 준비: 클래스 또는 인터페이스에 필요한 메..
클라우드 네이티브 환경에서는 스케일을 쉽게 변경할 수 있는 것이 장점입니다. 이러한 환경에서 리소스를 쉽게 컨트롤할 수 있어야 합니다. 동시에 수십개, 수백개의 컨테이너를 배포하고 관리하는 상황에서 아래의 어려움를 해결해야 합니다 1. 배포 관리 : 호스트의 리소스에 맞춰 어떤 컨테이너를 할당해야 하나, 배포 상태를 최소한의 변경으로 유지할 수 있는가? 2. 제어와 모니터링 : 구동 중인 컨테이너 상태를 어떻게 유지하고 관리할 것인가 3. 스케일링 : 쉽게 자원을 줄이고 늘릴 수 있는가 4. 네트워킹 : 운영되는 컨테이너간의 통신은 어떻게 할 것인가? 위의 4가지 어려움을 쉽게해결해주는 것이 컨테이너 오케스트레이션입니다. 이 중 하나가 저희가 아는 쿠버네티스입니다. 쿠버네티스 특징은 기능단위의 모듈화, ..