반응형

Cluster 상태 모니터링

삭제 작업 중 Kibana의 Monitoring이나 /_cat/health API를 사용하여 클러스터 상태를 모니터링 할 수 있다

GET /_cat/health?v=true

curl 코드

curl -X GET "localhost:9200/_cat/health?v=true&pretty"

 

결과 예시

cluster       status node.total node.data shards pri relo init unassign unassign.pri pending_tasks max_task_wait_time active_shards_percent
elasticsearch green           1         1      1   1    0    0        0            0             0                  -                100.0%

 

상태(status)

- grenn : 모든 샤드가 정상적으로 작동 중

- yellow : 일부 복제본 샤드가 활성화되지 않았지만, 데이터는 사용 가능

- red : 일부 데이터 샤드가 손실된 상태

 

노드 상태 모니터링

GET /_nodes/stats

curl코드

curl -X GET "localhost:9200/_nodes/stats?pretty"

 

출력 예시

- CPU 사용량

- Heap 메모리 사용량

- 디스크 사용량 및 가용량

샤드 상태 모니터링

GET /_cat/shards?v

curl 코드

curl -X GET "localhost:9200/_cat/shards?v=true&pretty"

출력예시 : 

index       shard prirep state   docs  store ip            node
user_data   0     p      STARTED 10000 5mb   192.168.1.10 node-1
user_data   1     r      STARTED 10000 5mb   192.168.1.11 node-2

p : primary 샤드

r : replica 샤드

 

state : STARTED, RELOCATING, INITIALIZING, UNASSIGNED 등의 사앹 확인 가능

 

작업 큐 상태 확인

GET /_cat/thread_pool?v

curl 코드

crul -X GET "localhost:9200./_cat/shards?v=true&pretty"

출력 예시

node_id   name    active queue rejected
node-1    write   2      15    0
node-2    search  0      10    5

queue : 작업 대기열의 크기

rejected : 처리할 수 없어 거부된 작업 수(거부 작업이 많다면 리소스가 부족하다는 신호다)

 

_tasks를 통해 특정 작업 모니터링 하기(나의 경우 delete_by_query)

curl 코드

curl -X GET "localhost:9200/_tasks?detailed=true&actions=*/delete/byquery&pretty"

출력예시

{
  "nodes": {
    "node-1": {
      "tasks": {
        "node-1:12345": {
          "action": "indices:data/write/delete/byquery",
          "status": {
            "total": 100000,
            "deleted": 5000,
            "version_conflicts": 0,
            "throttled_millis": 0
          }
        }
      }
    }
  }
}

 

 

굿굿

 

반응형
반응형

Waiting for cache lock: Could not get lock /var/lib/dpkg/lock-frontend.에러

1. 프로세스를 종료시킨다

sudo killall apt apt-get

 

2. 위 방법으로 효과가 없다면 디렉토리 삭제

sudo rm /var/lib/apt/lists/lock
sudo rm /var/cache/apt/archives/lock
sudo rm /var/lib/dpkg/lock*

 

3. 패키지 재구성

sudo dpkg --configure -a

 

4. 마무리

sudo apt update

 

추가로 터미널이나, bash 창을 닫았다가 열어서 시도하기

운영 체제 재부팅

등으로 해결하였다는 분들도 있었다.

 

참고

https://askubuntu.com/questions/1109982/e-could-not-get-lock-var-lib-dpkg-lock-frontend-open-11-resource-temporari

 

E: Could not get lock /var/lib/dpkg/lock-frontend - open (11: Resource temporarily unavailable)

I'm trying to run this command in the terminal: sudo apt install software-properties-common This is the error message I get: E: Could not get lock /var/lib/dpkg/lock-frontend - open (11: Resource

askubuntu.com

 

반응형
반응형

엘라스틱 서치 작업을 해야하는데

RDBMS만 다루다보니 삭제 작업에서 락이 발생하지는 않을지 궁금하여 찾아본 내용 정리

 

*RDBMS 는 MySQL 기준으로 작성

 

혹시 잘못된 내용이 있다면 댓글 주시면 감사하겠습니다.

MySQL의 동작방식

REBMS에서 데이터 삭제가 조회/수정에 영향을 미치는 이유

- 트랙잭션 관리 : MySQL은 ACID를 준수한다. 데이터를 삭제할 때, 해당 행을 잠그고 삭제가 완료되기 전까지 다른작업이 영향을 받을 수 있다.

 

- 물리적 삭제 : MySQL은 데이터를 삭제할 때 디스크에서 데이터를 즉시 제거한다.

 

- 락의 종류

행 레벨 락 : 삭제가 진행 중인 특정 행에 대해 검색/삽입 작업이 대기 상태가 된다.

테이블 락 : 대량 삭제가 테이블에 걸리는 락을 유발할 경우, 모든 작업이 영향을 받을 수 있다.

 

Elasticsearch의 동작방식

NoSQL기반으로 분산형 아키텍처라 데이터 삭제 방식이 RDBMS와 다르다

 

삭제 마킹

엘라스틱에서 데이터를 삭제할 때 해당 문서를 디스크에서 즉시 제거하는게 아니라 삭제된 것으로 표시만 한다

물리적 삭제는 나중에 처리됨

삭제 마킹된 데이터는 백그라운드 병합 작업 중 물리적으로 디스크에서 제거된다.

따라서 삭제 작업이 진행 중일 때도 검색 및 삽입 작업이 계속 정상적으로 이루어질 수 있다.

 

Elasticsearch 에서 검색과 삽입이 영향을 받지 않는 이유 

1. 읽기/쓰기 동시성 처리 :

- 샤드 기반 분산 처리를 사용하여 데이터가 여러 샤드에 분산되어 작업이 특정 샤드에서 이루어져도 다른 샤드에서는 검색 및 삽입 작업이 독립적으로 실행

- 검색과 삭제 작업은 서로 다른 리소스를 사용하므로, 병렬 처리 가능

 

2. 삭제가 논리적으로 처리됨 :

- 삭제는 문서 검색 결과에서 제외하는 논리적 작업에 불과하여 문서가 삭제되더라도 검색은 실시간으로 작동

 

3. document 기반 데이터 모델 :

- 데이터를 독립적인 문서 단위로 저장

- 각 문서가 고유하여 삭제 작업이 진행 중이라도 다른 문서에 삽입되거나 검색될 수 있음

 

특징 MySQL Elasticsearch
삭제 방식 물리적 삭제 논리적 삭제 (삭제 마킹)
데이터 모델 행(row) 단위 관리 독립적인 문서(Document) 단위 관리
트랜잭션 강제성 ACID (강력한 일관성) 최종적 일관성 (Eventual Consistency)
삭제 중 검색/삽입 영향 락 발생 가능성 높음 영향 거의 없음
삭제 처리 시점 즉시 (삭제와 병합 동시 진행) 삭제는 나중에 병합 작업에서 처리

 

반응형
반응형

Elasticsearch란

검색 및 분석을 위한 분산형 오픈소스 데이터베이스

데이터를 index라는 구조로 저장하고, 이를 통해 빠르고 유연한 검색이 가능

 

Document : Elasticsearch에서 데이터의 최소 단위(예 : JSON 형식의 데이터)

Index : Document들이 모여있는 데이터베이스와 유사한 개념

Cluster/Node : 여러 개의 Index와 데이터를 저장하는 서버환경

 


Elasticsearch  데이터 삭제 방법

 

1. 인덱스 전체 삭제

DELETE /index_name

 

2. 조건에 맞는 Document 만 삭제

POST /index_name/_delete_by_query
{
  "query": {
    "match": {
      "field_name": "value" // field_name, value 특정 조건
    }
  }
}

3. Document ID 로 특정 데이터 삭제

DELETE /user_data/_doc/123

 

 

엘라스틱서치 데이터 삭제시 주의해야할 사항으로는

데이터 복구가 불가능하기 때문에 삭제한 중요한 데이터는 삭제 전 백업이 꼭 필요하다.

 

Elasticsearch 대량 삭제가 다른 작업에 미치는 영향

읽기

Elasticsearch는 분산형 아키텍처를 사용하기 때문에, 대량 삭제 작업이 진행되는 동안 검색 및 조회 가능하다

삭제 작업이 클러스터에 높은 부하를 줄 경우, 일부 검색 쿼리의 응답 속도가 느려질 수 있다

쓰기

삭제 작업은 노드 리소스를 소비하므로, 동시에 대량 데이터를 추가하거나 갱신하려는 작업이 진행중이면 성능 저하가 발생할 수 있다

 

_delete_by_query  사용시 데이터를 검색하고 삭제하므로 CPU와 디스크 I/O를 많이 사용

작업의 양이 많아질 경우 성능 서하가 발생할 수 있다

 

성능 저하를 최소화하는 방법

. 사용자 활동이 적은시간(업무 외 시간, 야간)에 삭제 작업을 진행

. 삭제 작업을 분할 처리

: 삭제 작업을 한번에 하지 않고 적게 나눠서 삭제한다.

. Throttling 설정

: request_per_second 값을 설정하여 삭제 제한 설정

ex) 초당 100건 삭제 제한

POST /index_name/_delete_by_query?requests_per_second=100
{
  "query": {
    "match_all": {}
  }
}

. Cluster 상태 모니터링

Kibana의 Monitoring 이나

/_cat/health

명령어를 사용해 클러스터 상태 모니터링

* 상태가 green  일 경우 클러스터가 안정적 상태라는 뜻

 


회사 업무 작업 전 정리 중.

연습삼에 로컬 컴퓨터에 환경을 구축해서 실험해볼 예정이다.

반응형
반응형

DB 테이블 리스트 조회 방법

회사에서 업무를 하다보면 테이블 조회할 일이 많은데

ERD가 문서화되어있지 않으면 일단 내가 어떤 테이블을 조회할 수 있는지 어떤 테이블이 있는지조차 몰라서

문의가 들어왔을 때

'엥...' 하고 있을 때가 있다

 

최근 새로운 시스템 업무를 조금씩 인수인계 받기 시작하면서 생소한 테이블도 조회를 하고 있는데 앞으로 내가 어떤 테이블을 다룰지 미리미리 확인을 하기 위해서 권한을 부여받은 DB의 테이블을 미리 확인해보려고 하였다.

MySQL

SHOW TABLES;

MySQL에서는 show table로 현재 선택된 데이터베이스 내의 모든 테이블 출력 가능

SHOW TABLES FROM 데이터베이스명;

특정 데이터베이스의 테이블을 조회하려면 데이터베이스 명을 입력한다

SELECT table_name 
FROM information_schema.tables
WHERE table_schema = '데이터베이스명' AND table_name LIKE '%키워드%';

특정 조건을 만족하는 테이블만 필터링 하기 위해서 infomation_schema.table 을 사용할 수있다

 

Oracle

Oracle에서는 ALL_TABLES 뷰를 통해 데이터베이스의 모든 테이블을 조회할 수 있지만

테이블을 스키마별로 관리하고 있으므로 스키마에 따라결과가 달라질 수 있다.

SELECT table_name 
FROM all_tables
WHERE owner = '스키마명';

테이블 이름으로 필터링 가능

SELECT table_name
FROM all_tables
WHERE owner = '스키마명' AND table_name LIKE '%키워드%';

Oracle에서는 ALL_TABLES, USER_TABLES, DBA_TABLES 세 가지 테이블 뷰가 있는데, 각 뷰는 다음과 같은 용도로 사용됩니다:

  • ALL_TABLES: 현재 사용자가 접근할 수 있는 모든 테이블
  • USER_TABLES: 현재 사용자에게 속한 테이블만 조회
  • DBA_TABLES: 데이터베이스 내 모든 테이블 조회 (DBA 권한 필요)
반응형
반응형

https://pypi.org/project/jaconv/

 

jaconv

Pure-Python Japanese character interconverter for Hiragana, Katakana, Hankaku, Zenkaku and more

pypi.org

다운로드

pip install jaconv

 

기능

히라가나 -> 가타카나 전환

가타카나 -> 히라가나 전환

가능하다

 

영어 -> 히라가나

히라가나 -> 영어 기능도 제공한다고 위키에는 나와 있으나,

실험해보니 해당 기능은 부족한 부분이 있는 것으로 보인다

 

import jaconv

# Hiragana to Katakana
jaconv.hira2kata('ともえまみ')
# => 'トモエマミ'

# Hiragana to half-width Katakana
jaconv.hira2hkata('ともえまみ')
# => 'トモエマミ'

# Katakana to Hiragana
jaconv.kata2hira('巴マミ')
# => '巴まみ'

# half-width character to full-width character
# default parameters are followings: kana=True, ascii=False, digit=False
jaconv.h2z('ティロ・フィナーレ')
# => 'ティロ・フィナーレ'

# half-width character to full-width character
# but only ascii characters
jaconv.h2z('abc', kana=False, ascii=True, digit=False)
# => 'abc'

# half-width character to full-width character
# but only digit characters
jaconv.h2z('123', kana=False, ascii=False, digit=True)
# => '123'

# half-width character to full-width character
# except half-width Katakana
jaconv.h2z('アabc123', kana=False, digit=True, ascii=True)
# => 'アabc123'

# an alias of h2z
jaconv.hankaku2zenkaku('ティロ・フィナーレabc123')
# => 'ティロ・フィナーレabc123'

# full-width character to half-width character
# default parameters are followings: kana=True, ascii=False, digit=False
jaconv.z2h('ティロ・フィナーレ')
# => 'ティロ・フィナーレ'

# full-width character to half-width character
# but only ascii characters
jaconv.z2h('abc', kana=False, ascii=True, digit=False)
# => 'abc'

# full-width character to half-width character
# but only digit characters
jaconv.z2h('123', kana=False, ascii=False, digit=True)
# => '123'

# full-width character to half-width character
# except full-width Katakana
jaconv.z2h('アabc123', kana=False, digit=True, ascii=True)
# => 'アabc123'

# an alias of z2h
jaconv.zenkaku2hankaku('ティロ・フィナーレabc123')
# => 'ティロ・フィナーレabc123'

# normalize
jaconv.normalize('ティロ・フィナ〜レ', 'NFKC')
# => 'ティロ・フィナーレ'

# Hiragana to alphabet
jaconv.kana2alphabet('じゃぱん')
# => 'japan'

# Alphabet to Hiragana
jaconv.alphabet2kana('japan')
# => 'じゃぱん'

# Katakana to Alphabet
jaconv.kata2alphabet('ケツイ')
# => 'ketsui'

# Alphabet to Katakana
jaconv.alphabet2kata('namba')
# => 'ナンバ'

# Hiragana to Julius's phoneme format
jaconv.hiragana2julius('てんきすごくいいいいいい')
# => 't e N k i s u g o k u i:'

히라가나 - 가타카나 가타카나 - 히라가나 전환만 필요한 경우 해당 라이브러리를 이용하면 편리하다

반응형
반응형

python으로 pip 설치를 진행하다가 에러가 발생하였다

 

에러

[notice] A new release of pip is available: 24.2 -> 24.3.1
[notice] To update, run: python.exe -m pip install --upgrade pip

 

에러의 원인은 버전이 낮아서 발생하는 것으로 pip upgrade가 필요하다

 

해결방법

사실 해당 에러는 매우 간단하다

python.exe -m pip install --upgrade pip

파이썬이 안내해주는 방식 그대로 사용하면 해결 가능하다!

 

해당 방법으로 pip를 업그레이드한 후 본래 사용하고 싶었던 명령어를 사용할 수 있었다.

반응형
반응형

Python  가상환경 사용하기

Python에서는 가상 환경을 사용할 수 있고 특병 프로젝트에 맞춰서 패키지를 다르게 독립적으로 설정해줄 수 있다

버전관리나 동일한 환경에서 다른사람들과 작업하기 편리하다

Python 가상환경 생성하기

python -m venv '가상 환경 이름'

Python 가상환경 활성화하기

생성된 가상 환경으로 이동 후 활성화

cd '가상 환경 이름 '
source Scripts/activate

해당 명령어를 입력하면 하단에('가상환경이름') 가상환경이 연결된걸 확인할 수 있다.

나의 경우 venv로 대충 지음

 

bash에 입력시

 

sou + Tab S + Tab a + Tab 

Tab 입력시 간편하게 자동완성 해준다

가상 환경에 패키지 설치

가상 환경에 접속 후 pip를 사용해서 패키지를 설치할 수 있다

pip install requests

위의 명령어를 입력하면 전역 환경에는 깔리지 않지만 나의 venv환경에서는 requests 라이브러리가 추가된다!

가상환경 비활성화

deactivate

입력하면 bash 하단의('가상환경이름') 이 사라진다

 

가상환경 삭제

가상환경 삭제는 간단하게 해당 가상환경이 포함된 폴더늘 삭제 해주면 된다

rmdir

 

추가 팁

내가 설치한 패키지와 버전을 한번에 txt 파일로 뽑아낼 수 있다.

pip freeze > requirements.txt

그리고 이대로 설치도 가능하다

pip install -r requirements.txt
반응형
반응형

 

사용자가 웹 사이트에 접속했을 때 웹으로 접속했는지, 모바일로 접속했는지에 따라 다른 화면을 보여주려고 한다.

그러기 위해서는 현재 접속한 브라우저가 웹인지 모바일로 접속했는지에 대한 구분을 할 수 있어야 해서

방법을 찾아봤고 2가지 방법을 찾았다!

 

navigator.userAgent를 사용해 구분하는 방법

navigator.userAgent는 설치가 필요하지는 않다!

 

const [browser, setBrowser] = useState()

.
.
.
// 초기 렌더링 후 한 번만 실행하기 위해 useEffect 사용
    useEffect(()=>{
        const user = navigator.userAgent;
        // 기본 환경 웹으로 설정
        setBrowser("web")
    	
        // userAgent 문자열에 iPhone, Android 일 경우 모바일로 업데이트
        if ( user.indexOf("iPhone") > -1 || user.indexOf("Android") > -1 ) {
            setBrowser("mobile")
        }
    },[])

navigator.userAgent는 운영 체제 정보를 문자열로 반환해서 해당 문자열을 확인하여 웹과 모바일을 구분한다.

return ( 
        browser === "web" ? 
        <>
            <div>
			...
            </div>
        </> :
        <>
        	<div>
			...
           	</div>
        </>

변수 === "변수1" ? <></> : <></>

이런 형식으로 다른 div를 노출하도록 만들었다

 

 

두번째 방법으로 찾은거

react-device-detect를 설치하여 환경 구분

https://www.npmjs.com/package/react-device-detect

 

react-device-detect

Detect device type and render your component according to it. Latest version: 2.2.3, last published: 2 years ago. Start using react-device-detect in your project by running `npm i react-device-detect`. There are 1195 other projects in the npm registry usin

www.npmjs.com

1. react-device-detect를 설치한다

npm install --save react-device-detect

2. 사용할 페이지에서 react-device-detect를 import하여 사용

import React, { useState } from 'react';

import { BrowserView, MobileView } from 'react-device-detect';


function Main() {
    return ( 
        <div className='container'>
            <BrowserView>
                <Content
                </Content>
            </BrowserView>
            <MobileView>
                <ContentMobile
                </ContentMobile>
            </MobileView>
        </div>
     );
}

export default Main;​

웹뷰와 모바일뷰의 컴포넌트를 따로 생성하여 불러오도록 만들었다

이렇게 작성하면 웹에서 접속시 Content를 모바일에서 접속시 ContentMobile을 불러와서 화면에 띄워준다!

단순히 화면 뿐만 아니라 import 해오는 패키지가 다른 경우에 이걸 사용해서 페이지를 분리했다

 

반응형
반응형

현재 개인 프로젝트를 하면서 백엔드 서버 구성 없이 프론트엔드만으로 사이트를 구성중이다

사이트 사용자들이 나에게 의견이나 후기? 등을 작성해서 보내줄 수 있도록 이메일 보내기(Contact Us)를 만들려고

백엔드 구성 없이 이메일 보내는 시스템을 만들어보려고 했다

 

그렇게 선택한 것!

EmailJS

. 백엔드 구성 필요 없음

. 간단

. 템플릿 커스텀 가능

 

이런저런 이유로 EmailJS를 사용하기로 했다!

 

EmailJS 사용하기

 

https://www.emailjs.com/

 

Send email directly from your code | EmailJS

No server side code required. Add static or dynamic attachments, dynamic parameters, captcha code and more. Start with our free tier!

www.emailjs.com

일단 페이지 접속

EmailJS를 사용하기 위해서는 위 페이지에 들어가서 가입을 해야한다.

가입하면 이 화면처럼 나오는데 Add New Service를 눌러서 서비스를 추가한다

이메일을 연결한다

 

 

일단 테스트로 이렇게 커스텀해봤다

위의 Test It 버튼을 누르면 TEST도 가능한데, TEST도 하루 메일 보낼 수 있는 양을 차감한다

...

const [formData, setFormData] = useState({
    name : 'name',
    message : 'sample'
})    


...

const sendEmail = (e) =>{

    emailjs.send("service_ID","template_ID",formData,'PUBLICC_KEY')
    .then((response) => {
        console.log("success",response.status, response.text)
        setFormData()
    },(error) => {
        console.log('FAILED',error)
    })
}

...

<form>
    <div>
        <input type="text" placeholder="이름" name="name" onChange={handleChange}></input>
    </div>
    <div>
        <input type="textarea" placeholder="내용" name="message" onChange={handleChange}></input>
    </div>
    <button type="submit" onClick={sendEmail}>보내기</button>
</form>

 

실제 보내기 위해서는 위에서 커스텀 한

{{ name }}

{{ message }}

를 포함한 form을 만들어주고 입력한 값이 보내지도록 한다

 

메일을 실제로 보내기 위해서는

SERVICE ID

TEMPLATE ID

PUBLIC KEY

가 필요한데 각각 아래 이미지 부분에서 확인할 수 있다

 

SERVICE ID

TEMPLATE ID

PUBLIC KEY

 

이렇게 필요한 ID, KEY를 입력하고 sendEmail을 하면 메일이 내가 설정한 폼의 형태로 온다!

 

무료 버전은 한 달 동안 200 개의 메시지를 수신받을 수 있고,

남은 메일 수는 Account > Subscription Remaining quota 에서 확인 할 수 있다.

 

사이트 이요자가 나에게 메일을 보낼 수 있는 시스템으로 이용도 가능하지만 특정 행동에 코드를 심어두면

사용자가 특정 페이지를 방문하거나 클릭 혹은 이동 했을 때 나에게 메일이 올 수 있도록 설정하는 것도 가능할 것 같다.

 

나는 일단 지금 프로젝트에서는 사용자들이 나에게 메일을 보낼 수 있도록 하는 용도로만 사용할 것 같다.

 

어렵지 않아서 사용해볼만한듯!

반응형

+ Recent posts