Virtual Threads는 JDK 19에서 처음 소개된 기능으로, Java의 스레드 모델을 개선하기 위한 중요한 혁신 중 하나입니다. 기존의 Java 스레드 모델은 운영 체제(OS) 레벨의 스레드를 사용하여 애플리케이션의 동시성을 처리했지만, 이 모델에는 몇 가지 한계가 있었습니다. 특히, 많은 수의 스레드를 생성할 때 메모리와 성능의 제약이 발생할 수 있었습니다. Virtual Threads는 이러한 문제를 해결하기 위해 도입되었습니다.

 

이미지 출쳐 : https://dev.to/jackynote/completablefuture-vs-virtual-thread-in-java-21-1gfp

 

CompletableFuture vs Virtual Thread in Java 21

Some of my knowledge for the first time reading about the features of Java 21, there will be many...

dev.to

 

Virtual Threads의 주요 개념

  1. 경량 스레드: Virtual Threads는 매우 경량화된 스레드로, 수천 또는 수만 개의 스레드를 생성하더라도 시스템 자원에 크게 부담을 주지 않습니다. 이는 기존의 OS 스레드와 비교했을 때 매우 효율적인 메모리 사용과 스케줄링을 가능하게 합니다.
  2. 비동기 코드의 동기적 표현: Virtual Threads를 사용하면, 비동기적으로 작성된 코드도 동기 코드처럼 쉽게 작성할 수 있습니다. 즉, 비동기 코드에서 흔히 사용되는 콜백(callback) 또는 복잡한 Future/CompletableFuture 체인을 사용할 필요 없이, 마치 동기 코드처럼 간단하게 비동기 작업을 처리할 수 있습니다.
  3. 운영 체제와의 분리: Virtual Threads는 Java의 사용자 레벨에서 관리되며, 운영 체제의 스레드와는 별도로 동작합니다. 이는 Java 런타임 환경에서 직접 스레드를 관리하고, OS의 스케줄러에 의존하지 않는다는 것을 의미합니다.
  4. 큰 수의 스레드 지원: Virtual Threads를 사용하면, 대규모 동시성을 필요로 하는 애플리케이션에서 수십만 개의 스레드를 효율적으로 운영할 수 있습니다. 이는 특히 서버 애플리케이션에서 많은 클라이언트 요청을 동시에 처리해야 하는 경우에 유용합니다.
  5. 간단한 사용: Virtual Threads는 기존의 Thread API와 매우 유사한 방식으로 사용할 수 있기 때문에, 개발자가 새로운 API나 개념을 학습할 필요 없이 쉽게 활용할 수 있습니다.

사용 예시

Thread.startVirtualThread(() -> {
    // 여기에 작업을 수행하는 코드 작성
});

 

or

Thread.ofVirtual().start(() -> {
    // Virtual Thread에서 실행할 코드
});

Virtual Threads의 장점

  • 자원 효율성: 기존의 OS 스레드보다 훨씬 적은 메모리를 사용하므로, 더 많은 동시 작업을 처리할 수 있습니다.
  • 단순성: 비동기 코드를 동기 코드처럼 작성할 수 있어 코드의 가독성과 유지보수성이 향상됩니다.
  • 확장성: 대규모 동시성을 필요로 하는 시스템에서도 높은 성능을 유지할 수 있습니다.

 

Virtual Threads의 단점

  • 스레드 수의 증가: Virtual Threads는 기존 스레드보다 훨씬 더 많은 수의 스레드를 생성할 수 있으므로, 디버깅이나 모니터링 과정에서 어떤 스레드가 어떤 작업을 수행하는지 추적하는 것이 어려울 수 있습니다. 기존의 디버깅 도구와 방법이 잘 작동하지 않을 가능성이 있습니다.
  • 디버깅 도구의 적응 필요: 많은 디버깅 및 모니터링 도구가 전통적인 OS 스레드를 기반으로 만들어졌기 때문에, Virtual Threads에 맞춰 적응하지 못한 도구들은 효과적이지 않을 수 있습니다. 이로 인해 개발자는 새로운 도구나 방식을 배워야 할 필요가 있습니다.
  • 블로킹 호출 문제: Virtual Threads는 기본적으로 비동기 작업을 효율적으로 처리하기 위해 설계되었습니다. 그러나 네트워크 호출이나 파일 I/O 등에서 블로킹 작업이 발생할 경우, Virtual Threads의 장점이 약화될 수 있습니다. Java 표준 라이브러리 내의 일부 API는 여전히 블로킹 방식으로 동작하기 때문에, 잘못된 사용은 성능 저하로 이어질 수 있습니다.
  • 블로킹과 비동기 혼용의 복잡성: 기존의 코드베이스에서 블로킹 호출과 비동기 호출이 혼용되어 있을 때, 이를 Virtual Threads로 변환하는 작업은 까다로울 수 있습니다. 모든 코드가 비동기적으로 동작하도록 하려면, 코드 리팩토링이 필요할 수 있습니다.
  • 제한된 스케줄링 제어: Virtual Threads는 Java 런타임에 의해 관리되므로, 개발자가 스레드의 우선순위나 스케줄링 정책을 세밀하게 제어하기 어렵습니다. 특정 스레드가 더 높은 우선순위를 가져야 하는 상황에서는 기존의 OS 스레드보다 제어가 어렵습니다.
  • 컨텍스트 스위칭 오버헤드: Virtual Threads는 매우 경량화되었지만, 대규모 애플리케이션에서 여전히 컨텍스트 스위칭과 관련된 오버헤드가 발생할 수 있습니다. 이는 매우 많은 수의 Virtual Threads를 사용할 때 성능 저하로 이어질 수 있습니다.

 

결론

Virtual Threads는 Java 애플리케이션에서 동시성을 처리하는 방식에 큰 변화를 가져왔지만, 모든 상황에서 무조건적으로 더 나은 선택은 아닙니다. 특히, 기존 시스템과의 호환성, 디버깅 및 모니터링의 복잡성, 블로킹 작업과의 조화 문제 등을 잘 이해하고, 상황에 맞게 적절히 사용해야 합니다. 이러한 단점과 제약을 인식하고, Virtual Threads의 장점을 극대화할 수 있는 방법을 모색하는 것이 중요합니다.

'프로그래밍언어 > JAVA' 카테고리의 다른 글

hashcode와 equals  (0) 2024.08.05
Hibernate ?  (0) 2024.03.31
순수 JAVA JPA  (0) 2024.03.17
getDeclaredConstructor().newInstance()?  (0) 2024.03.16
Reflection API란?  (0) 2024.03.16

이번에 백엔드 개발중에 '&' 포함된 특수문자가 들어가면서 url에서 파라미터가 검색이 안되는 현상이 발생했다.

 

이후 base 64로 인코딩을 하여 디코딩해서 사용했는데 어떠한 특수한 경우에 이와 같은 오류가 발생했다.

 

오류:

Uncaught DOMException: Failed to execute 'btoa' on 'Window': The string to be encoded contains characters outside of the Latin1 range.

 

이전 :

function base64(str) {
    return btoa(str);
}

 

변경을 해줬다

function utf8ToBase64(str) {
    return btoa(unescape(encodeURIComponent(str)));
}

const originalString = "all"; // 포함된 UTF-8 문자열
const encodedString = utf8ToBase64(originalString);

console.log(encodedString); //

 

문제는 여기서 또 발생하였다.

 

오류:

illegal base64 character 20; nested exception is java.lang.illegalargumentexception: illegal base64 character 20

 

이부분에 이상했던점이 한글을 인코딩하는데,

front  부분에서 특수문자인 '+'가 들어가게 되었고, url에선 '+'를 공백처리해버려서 디코딩이 잘되지 않았습니다.

 

그래서 이를 해결하기 위해

 

Hex 인코딩을 하게되었습니다. 

 

해결:

프론트 : 

function utf8ToHex(str) {
    const utf8Bytes = new TextEncoder().encode(str);
    return Array.from(utf8Bytes).map(byte => byte.toString(16).padStart(2, '0')).join('');
}

const originalString = "안녕하세요"; 
const encodedHex = utf8ToHex(originalString);

console.log(encodedHex);

 

백엔드:


public String hexDecode(String encodedHex){
  byte[] decodedBytes = new byte[encodedHex.length() / 2];
        for (int i = 0; i < encodedHex.length(); i += 2) {
            decodedBytes[i / 2] = (byte) ((Character.digit(encodedHex.charAt(i), 16) << 4)
                    + Character.digit(encodedHex.charAt(i + 1), 16));
        }
        String decodedString = new String(decodedBytes, StandardCharsets.UTF_8);
        return decodedString;
}

 

음 이걸 적게된건 단순하게 equals와 hashcode에 관련된 글을 우연히 보게 되었다.

 

equals는 항상 자주 쓰는거라 그렇다 치는데 hashcode는 메서드를 직접 잘 사용하지 않는다.

 

대신에 hashcode와 관련된 컬랙션  ( 예: HashMap, HashSet, Hashtable) 를 주로 사용한다.

(자세히 안 알아본 내 잘못이 크다.  자료구나, 알고리즘 공부하면 당연하게 hashmap을 사용해서 너무 쉽게 봤던것 같다.)

그렇다면 하나씩 확인해보자.

equals() 메소드

equals() 메소드는 두 객체가 "논리적으로 같은지"를 비교합니다. 기본적으로 Object 클래스의 equals() 메소드는 두 객체의 참조를 비교하지만, 이를 오버라이드하여 객체의 속성을 비교할 수 있습니다.

@Override
public boolean equals(Object obj) {
    if (this == obj) return true;
    if (obj == null || getClass() != obj.getClass()) return false;
    MyClass myClass = (MyClass) obj;
    return field1 == myClass.field1 &&
           Objects.equals(field2, myClass.field2);
}

 

hashCode() 메소드

hashCode() 메소드는 객체의 해시 코드를 반환합니다. 이 값은 객체를 해시 기반 컬렉션에서 사용할 때 사용됩니다. hashCode() 메소드를 오버라이드할 때는 equals() 메소드도 함께 오버라이드해야 하며, 이 둘은 다음 계약을 준수해야 합니다:

  1. 일관성: 같은 객체에 대해 여러 번 호출된 hashCode()는 항상 같은 값을 반환해야 합니다.
  2. equals()와의 일관성: 두 객체가 equals() 메소드로 같다고 판별되면, 그들의 hashCode()는 반드시 같아야 합니다.
  3. 다름: 두 객체가 equals() 메소드로 다르다고 판별되더라도, hashCode() 값이 반드시 다를 필요는 없습니다. 그러나 다른 객체에 대해서는 가능한 한 다른 해시 코드를 반환해야 합니다.
@Override
public int hashCode() {
    return Objects.hash(field1, field2);
}

예제 클래스

다음은 equals()와 hashCode() 메소드를 오버라이드한 예제 클래스입니다:

import java.util.Objects;

public class MyClass {
    private int field1;
    private String field2;

    public MyClass(int field1, String field2) {
        this.field1 = field1;
        this.field2 = field2;
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        MyClass myClass = (MyClass) o;
        return field1 == myClass.field1 && Objects.equals(field2, myClass.field2);
    }

    @Override
    public int hashCode() {
        return Objects.hash(field1, field2);
    }
}

 

뭐 사실 equals는 워낙 자주 사용하다보니 잘알것이다. 다만 hashcode는  한번쯤 무엇인지 확인해볼필요가 있다.

 

hashCode() 메소드는 주로 해시 기반 컬렉션 (예: HashMap, HashSet, Hashtable)에서 객체를 효율적으로 저장하고 검색하기 위해 사용됩니다.

 

일반적으로  List< HashMap> 을 자주 이용한다. 이때 hashMap의 객체의 효율적인 저장과 검색을 위해서 사용을한다. 

주요 이유

  1. 빠른 데이터 검색: 해시 기반 컬렉션은 평균적으로 O(1) 시간 복잡도로 데이터를 검색할 수 있습니다. 이는 객체의 해시 코드를 사용하여 해당 객체가 위치한 버킷을 빠르게 찾을 수 있기 때문입니다.
  2. 효율적인 데이터 저장: 해시 코드를 사용하면 데이터를 저장할 때 충돌을 줄일 수 있습니다. 해시 코드가 잘 분포되면 서로 다른 객체가 동일한 버킷에 저장되는 경우가 줄어들어, 해시 테이블의 성능이 향상됩니다.
  3. 일관성: equals() 메소드와 함께 사용될 때, 해시 코드는 객체의 논리적 동등성을 일관되게 유지하는 데 도움을 줍니다. 동일한 객체는 항상 동일한 해시 코드를 가져야 하며, 그렇지 않으면 해시 기반 컬렉션의 동작이 올바르게 작동하지 않을 수 있습니다.

여기서 hashcode는 메모리 주소가 아니다. 처음에 필자는 메모리 주소 인가 했다.

 

hashCode()와 객체 주소의 관계

  1. 기본 구현:
    • Object 클래스의 기본 hashCode() 메소드 구현은 객체의 메모리 주소를 기반으로 해시 코드를 생성할 수 있습니다. 이 때문에 객체가 동일하더라도 메모리 위치가 달라지면 해시 코드가 달라질 수 있습니다. 그러나, 이 기본 구현은 대부분의 경우 재정의됩니다.
  2. 사용자 정의 구현:
    • 대부분의 경우, 특히 해시 기반 컬렉션에서 올바르게 동작하기 위해, hashCode() 메소드는 객체의 상태(예: 필드 값)에 기반하여 해시 코드를 생성하도록 오버라이드됩니다. 이 경우, hashCode()는 객체의 메모리 주소와는 무관하게 객체의 내용을 기반으로 해시 코드를 계산합니다

'프로그래밍언어 > JAVA' 카테고리의 다른 글

Virtual Thread(가상 스레드)  (0) 2024.09.01
Hibernate ?  (0) 2024.03.31
순수 JAVA JPA  (0) 2024.03.17
getDeclaredConstructor().newInstance()?  (0) 2024.03.16
Reflection API란?  (0) 2024.03.16

https://www.acmicpc.net/problem/10999

문제가 좀 많이 어렵네요.

 

세그먼트 트리 + lazy propagation 알고리즘인데... 습 좀 많이 어렵네요.

관련해서 오답노트 정리 해볼 예정입니다.

import java.util.*;
import java.io.*;

public class Main {
    static int n;
    static long[] tree;
    static long[] lazy;

    public static void initTree(long[] arr) {
        buildTree(0, n - 1, 1, arr);
    }

    public static long buildTree(int start, int end, int node, long[] arr) {
        if (start == end) {
            return tree[node] = arr[start];
        }

        int mid = (start + end) / 2;
        return tree[node] = buildTree(start, mid, node * 2, arr) + buildTree(mid + 1, end, node * 2 + 1, arr);
    }

    public static void updateRange(int start, int end, int node, int rangeStart, int rangeEnd, long diff) {
        if (lazy[node] != 0) {
            tree[node] += (end - start + 1) * lazy[node];
            if (start != end) {
                lazy[node * 2] += lazy[node];
                lazy[node * 2 + 1] += lazy[node];
            }
            lazy[node] = 0;
        }

        if (rangeStart > end || rangeEnd < start) {
            return;
        }

        if (rangeStart <= start && end <= rangeEnd) {
            tree[node] += (end - start + 1) * diff;
            if (start != end) {
                lazy[node * 2] += diff;
                lazy[node * 2 + 1] += diff;
            }
            return;
        }

        int mid = (start + end) / 2;
        updateRange(start, mid, node * 2, rangeStart, rangeEnd, diff);
        updateRange(mid + 1, end, node * 2 + 1, rangeStart, rangeEnd, diff);
        tree[node] = tree[node * 2] + tree[node * 2 + 1];
    }

    public static long queryRange(int start, int end, int node, int queryStart, int queryEnd) {
        if (lazy[node] != 0) {
            tree[node] += (end - start + 1) * lazy[node];
            if (start != end) {
                lazy[node * 2] += lazy[node];
                lazy[node * 2 + 1] += lazy[node];
            }
            lazy[node] = 0;
        }

        if (queryStart > end || queryEnd < start) {
            return 0;
        }

        if (queryStart <= start && end <= queryEnd) {
            return tree[node];
        }

        int mid = (start + end) / 2;
        return queryRange(start, mid, node * 2, queryStart, queryEnd) + queryRange(mid + 1, end, node * 2 + 1, queryStart, queryEnd);
    }

    public static void main(String[] args) throws Exception {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
       
        StringTokenizer st = new StringTokenizer(br.readLine());

        n = Integer.parseInt(st.nextToken());
        int m = Integer.parseInt(st.nextToken());
        int k = Integer.parseInt(st.nextToken());

        long[] arr = new long[n];
        for (int i = 0; i < n; i++) {
            arr[i] = Long.parseLong(br.readLine());
        }

        tree = new long[n * 4];
        lazy = new long[n * 4];

        initTree(arr);

        for (int i = 0; i < m + k; i++) {
            st = new StringTokenizer(br.readLine());
            int type = Integer.parseInt(st.nextToken());
            if (type == 1) {
                int b = Integer.parseInt(st.nextToken()) - 1;
                int c = Integer.parseInt(st.nextToken()) - 1;
                long d = Long.parseLong(st.nextToken());
                updateRange(0, n - 1, 1, b, c, d);
            } else if (type == 2) {
                int b = Integer.parseInt(st.nextToken()) - 1;
                int c = Integer.parseInt(st.nextToken()) - 1;
                long result = queryRange(0, n - 1, 1, b, c);
                System.out.println(result);
            }
        }

    }
}

'알고리즘 공부' 카테고리의 다른 글

백준 수열과 쿼리 37  (2) 2024.07.15
백준 커피숍2  (0) 2024.04.17
백준 가계부  (0) 2024.04.10
백준 쵯소값과 최댓값  (0) 2024.04.08
백준 구간 합 구하기  (0) 2024.04.04

https://www.acmicpc.net/problem/18436

요즘 계속 회사 일이 바빠기도 했고 집에서 조금 쉬다보니 공부를 못했던것 같습니다.

오랜만에 푸는거라 시간이 조금 많이 걸렸네요 ㅠ

 

package test01;
import java.util.*;
import java.io.*;
public class Main {
	public static int n;
	public static int m;
	public static int k;
	public static long tree[];
	

	public static long buildingTree(int start ,int end, int node, long arr[]){
	
		if(start==end){
			if(arr[start]%2==0) {
				return tree[node]=1;
			}else {
				return  tree[node]=0;
			}
			
		}

		int mid=(start+end)/2; // 0+5 =2

		return tree[node]=buildingTree(start, mid,node*2,arr)+buildingTree(mid+1,end,node*2+1,arr);
		
	}

	public static long updateTree(int start,int end,int node,long newValue, int findIndex){
	
		if(findIndex<start||findIndex>end){
			return tree[node];
		}
		

		if(start==end){
			if(newValue % 2 == 0) {
				return tree[node] = 1;
			} else {
				return tree[node] = 0;
			}
		}
		
		

		int mid=(start+end)/2;

		return tree[node]=updateTree(start,mid,node*2,newValue,findIndex)+updateTree(mid+1,end,node*2+1,newValue,findIndex);
		

	}

	public static long select (int start,int end,int node,int left,int right){
	
		if(left>end||right<start){
			return 0;
		}
		

		if(left<=start&&end<=right){
			return tree[node];
		}
		
		int mid=(start+end)/2;

		return select(start,mid,node*2,left,right)+select(mid+1,end,node*2+1,left,right);
		

	}

	public static void main(String[] args) throws Exception {
		Scanner scan = new Scanner(System.in);
		 n =scan.nextInt();
		 long arr[]=new long[n];
		 for(int t=0;t<n;t++){
				long tmp=scan.nextLong();
				arr[t]=tmp;
		}
		 
		 m=scan.nextInt();
	
		tree=new long[n*4];
		
		buildingTree(0,n-1,1,arr);
	
		for(int t=0;t<m;t++){
			int a=scan.nextInt();
			int b = scan.nextInt();
			int c = scan.nextInt();
			if(a==1){
				//update
				if(arr[ b-1 ] %2 ==1 && c%2==0 ) {
					updateTree(0,n-1,1, c , b-1);
				}else if(arr[  (b-1) ] %2 ==0 && c%2==1 ){
					updateTree(0,n-1,1 ,c, b-1);
				}
				arr[b-1]=c;
				
			}else if(a == 2){
				// select
				long query = select(0, n - 1, 1, b - 1, c - 1);
				System.out.println(query);
			} else if(a == 3){
				// select
				long query = select(0, n - 1, 1, b - 1, c - 1);
				System.out.println((c - b + 1) - query);
			}
		}
	

	}
}

'알고리즘 공부' 카테고리의 다른 글

백준 - 구간 합 구하기2  (0) 2024.07.17
백준 커피숍2  (0) 2024.04.17
백준 가계부  (0) 2024.04.10
백준 쵯소값과 최댓값  (0) 2024.04.08
백준 구간 합 구하기  (0) 2024.04.04

설치:

https://www.elastic.co/kr/elasticsearch

 

Elasticsearch: 공식 분산형 검색 및 분석 엔진 | Elastic

Elasticsearch는 속도, 수평적 확장성, 안정성 및 간편한 관리를 위해 설계된 선도적인 분산형 RESTful 무료 오픈 소스 검색 및 분석 엔진입니다. 무료로 시작하세요....

www.elastic.co

1. Elasticsearch

Elasticsearch는 분산형 검색 및 분석 엔진으로, JSON 기반의 문서들을 색인하여 고속 검색 및 데이터 분석을 제공합니다.

설치 및 실행

  • Elastic의 공식 웹사이트에서 Elasticsearch를 다운로드하고 설치합니다.
  • elasticsearch.yml 설정 파일을 편집하여 필요한 설정을 변경합니다.
  • 터미널에서 bin/elasticsearch를 실행하여 Elasticsearch 서버를 시작합니다.

2. Logstash

Logstash는 다양한 소스에서 로그 및 이벤트 데이터를 수집하고 변환한 다음 Elasticsearch로 전달하는 역할을 합니다.

설치 및 실행

  • Elastic의 공식 웹사이트에서 Logstash를 다운로드하고 설치합니다.
  • logstash.conf와 같은 설정 파일을 만들어 다음과 같이 구성합니다
input {
  file {
    path => "/path/to/your/logfile.log"
    start_position => "beginning"
  }
}
filter {
  # 필요한 경우 필터 설정을 추가
}
output {
  elasticsearch {
    hosts => ["localhost:9200"]
    index => "log-index"
  }
}

3. Spring

Spring 애플리케이션에서 Elasticsearch와 통합하는 데는 spring-data-elasticsearch를 사용할 수 있습니다.

설치 및 사용

  • Spring 프로젝트에 spring-data-elasticsearch 의존성을 추가합니다.
<!-- Maven -->
<dependency>
  <groupId>org.springframework.boot</groupId>
  <artifactId>spring-boot-starter-data-elasticsearch</artifactId>
  <version>3.0.0</version>
</dependency>

 

application. yml

spring:
  elasticsearch:
    uris: http://localhost:9200

 

EntitiyClass

@Document(indexName = "your-index")
public class YourEntity {
  @Id
  private String id;
  private String field1;
  // 필드 추가
}

public interface YourEntityRepository extends ElasticsearchRepository<YourEntity, String> {
  // 맞춤형 쿼리 메소드 정의
}

' > ElasticSearch' 카테고리의 다른 글

log stash란?  (0) 2024.05.04
엘라스틱 서치 란?  (0) 2024.05.04

Logstash는 Elastic Stack의 일부로, 로그, 이벤트 및 기타 데이터 소스에서 데이터를 수집하고 변환하며 다양한 목적지로 전달하는 오픈 소스 데이터 처리 파이프라인입니다. Logstash를 통해 여러 소스에서 데이터 입력을 받아 이를 실시간으로 처리하여 Elasticsearch 같은 데이터 저장소로 전송할 수 있습니다.

Logstash의 주요 기능

  1. 입력(Input):
    • 파일, 데이터베이스, 메시지 큐, 네트워크 등 다양한 소스에서 데이터를 수집할 수 있습니다.
    • 예를 들어 파일에서 로그를 읽어오는 file 플러그인, 메시지 큐 시스템인 Kafka에서 읽어오는 kafka 플러그인 등이 있습니다.
  2. 필터(Filter):
    • 수집한 데이터를 변환, 파싱, 정규화 등의 작업을 통해 원하는 형식으로 변환할 수 있습니다.
    • 예를 들어 grok 필터는 정규 표현식을 사용하여 로그 데이터를 파싱하고 구조화된 데이터를 생성합니다.
  3. 출력(Output):
    • 처리된 데이터를 Elasticsearch, 파일, 데이터베이스, 메시지 큐 등 다양한 목적지로 전송할 수 있습니다.
    • 대표적으로 Elasticsearch에 데이터를 전송하는 elasticsearch 출력 플러그인, 로컬 파일로 데이터를 쓰는 file 플러그인이 있습니다.

 

 
 
 

' > ElasticSearch' 카테고리의 다른 글

엘라스틱 서치와 logstash , 스프링에서 사용법  (0) 2024.05.12
엘라스틱 서치 란?  (0) 2024.05.04

엘라스틱서치(Elasticsearch)는 강력하고 확장 가능한 오픈 소스 검색 엔진이자 분석 엔진입니다. Elasticsearch는 Apache Lucene 기반으로 구축되었으며, 대용량의 텍스트 데이터를 실시간으로 저장, 검색 및 분석하는 데 최적화되어 있습니다.

 

  1. 분산 아키텍처: 데이터는 여러 노드에 걸쳐 분산 저장될 수 있어 대용량 데이터를 처리하는 데 적합합니다.
  2. 실시간 검색 및 분석: 거의 실시간으로 검색 및 분석을 수행할 수 있어 빠른 응답 시간이 요구되는 애플리케이션에 적합합니다.
  3. RESTful API: Elasticsearch는 JSON 기반의 RESTful API를 제공하여 쉽게 통합 및 확장할 수 있습니다.
  4. 복잡한 쿼리 언어 지원: 다양한 형태의 검색, 필터링 및 집계를 위한 강력한 쿼리 언어를 지원합니다.
  5. 커뮤니티 및 생태계: Kibana와 같은 대시보드 도구나 Logstash 및 Beats와의 통합을 통해 ELK 스택을 구축하여 로그 및 이벤트 데이터를 처리하는 등 다양한 사용 사례를 지원합니다.

https://www.elastic.co/kr/elasticsearch

 

Elasticsearch: 공식 분산형 검색 및 분석 엔진 | Elastic

Elasticsearch는 속도, 수평적 확장성, 안정성 및 간편한 관리를 위해 설계된 선도적인 분산형 RESTful 무료 오픈 소스 검색 및 분석 엔진입니다. 무료로 시작하세요....

www.elastic.co

 

' > ElasticSearch' 카테고리의 다른 글

엘라스틱 서치와 logstash , 스프링에서 사용법  (0) 2024.05.12
log stash란?  (0) 2024.05.04

+ Recent posts