[컴] 요즘 swap 용량은?

스왑은 얼마나 크게 / 스왑 용량 / 메모리 용량 / swap size /

요즘 swap 용량은?

과거와 다르게 요즘 swap size 의 권장량이 변경됐다.

다음 글을 보면 과거 swap 은 큰 메모리를 쓰면, 큰 swap 공간을 잡도록 권장했다. 하지만 이제는 그렇지 않다. 2GB 보다 큰 메모리에서는 ram 용량정도이거나, ram 보다 작은 swap 크기를 사용하라고 권장한다.

과거에 당사는 메모리 크기의 증가에 대해 swap 공간 크기도 선형적으로 증가시키는 것을 권고하고 있었습니다. 더 엄격하게 말하자면, 시스템의 메모리 크기가 2 GB 까지라면 그 크기의 2 배의 swap 공간을 권고하였으며, 메모리 크기가 2 GB 이상이면 (메모리 크기 + 2GB) 의 swap 공간을 권고하였습니다.

테라바이트 급의 메모리를 가진 오늘날의 시스템과 플랫폼에서 이 방법은 더 이상 실용성이 없습니다. 아래의 가이드라인은 시스템이 가져야 할 스왑 공간을 결정하는데 도움이 될 것입니다.

설치된 RAM 용량 권장되는 스왑 용량 최대절전을 허용할때 권장되는 스왑용량
2GB or less RAM 용량의 2배 RAM 용량의 3배
> 2GB - 8GB RAM 용량 RAM 용량의 2배
> 8GB - 64GB 적어도 4GB ~ RAM 용량의 1 / 2 배 RAM 용량의 1.5배
> 64GB or more 적어도 4GB 최대절전이 권장되지 않음

참고로, 이것은 기본 swap memory 에 대한 이야기다. 만약 mongodb 처럼, swap memory 를 특별히 더 사용하게 되는 경우가 있다면, 더 많은 swap 을 잡아야 할 수 있다.

[컴] aws 에서 ebs block 은 자동으로 mount 가 되지 않는다.

terraform cloud init / cloud-init / ebs mount / volume /

aws 에서 ebs block 은 자동으로 mount 가 되지 않는다.

ebs_block_device vs aws_volume_attachment

다음처럼 ebs block 을 만드는 경우 ec2 instance 가 destroy 되고, 새로create 된다.

resource "aws_instance" "example_instance"{
    ebs_block_device{
      device_name = "/dev/sdf"
      volume_size = 500
      volume_type = "st1"
    }
    ebs_block_device{
      device_name = "/dev/sdg"
      volume_size = 500
      volume_type = "st1"
    }
}

그냥 volume 을 추가하고 attach 하고 싶다면, aws_volume_attachment을 이용하자.


[컴] vue-route 을 static file server 로 서비스 하는 법

serve/ 서브/ 서비스 하는 법 / vue route / 어떻게 / redirect /

vue-route 을 static file server 로 서비스 하는 법

vue-route 에서 url 로 route 을 할 수 있다. 이것을 HTML5 Mode 한다.

그러면 https://example.com/m/url 처럼 url 형식으로 route 가 가능하다.

그런데 이렇게 route 를 한 SPA(single page app) 인 경우, nginx 나 apache 같은 static file server 를 이용해서 serve 한다고 해보자.

그러면 web browser 에서 https://example.com/m/url 를 입력하면 ‘/m/url’ folder 에 접근할 것이다. 그런데 folder 가 없으니, 404 error 가 발생한다.

그래서 vue-route 의 home 으로 redirect 를 시켜줘야 한다.

간략하게 얘기하면, static server 에서 존재하지 않는 url 에 대해서 vue-route home 으로 보내주게 하면 된다. 예를 들어, https://example.com/m/url 로 간 경우, http://example.com/index.html 으로 보내주게 한다.

자세한 내용은 다음링크를 확인하자.

# 존재하지 않는 url 을 /index.html 로 보내는 설정
location / {
  try_files $uri $uri/ /index.html;
}

주의할 점

만약 아래와 같은 구조일 때

- <nginx_html_root>/
    + link/
        + index.html
    + css/
        + base.css

다음처럼 설정을 한다고 하자.

location / {
  try_files $uri $uri/ /link/index.html;
}

이 때, http://myurl.com/ 을 web browser 에 치면, /link/index.html 로 가지않고, / folder에 대한 access 를 시도한다. 그래서 403 forbidden 에러가 뜬다.

directory path 가 존재하지 않으면, /link/index.html 로 가게 돼서, vue-router 를 사용하게 되지만, 그렇지 않으면 directory access 를 시도 하게 된다.

이 때 방법은 403 error 가 날때 /link/index.html 로 redirection 시키는 것이다. 그러면 vue-router 에서 모두 처리하게 된다.

error_page  403              =301 /link/index.html;
const router = createRouter({
  history: createWebHistory(import.meta.env.BASE_URL),
  routes: [
    ...
    {
      // 정의된 path 이외의 모든 path
      // @see: https://stackoverflow.com/questions/50961082/vue-js-how-to-redirect-to-a-common-route-if-route-isnt-found/64817425#64817425
      path: '/:pathMatch(.*)*',
      component: NotFoundView
    }
  ]
})

[컴][웹] vue3 Naive ui 에서 Message component 사용

vuejs 3 / naive ui framwork / options api

vue3 Naive ui 에서 Message component 사용

여기서는 Options API 를 사용하는 예시를 보여주려 한다. Naive UI 에는 Composite API 의 형태로 나와있다.

useMessage 는 message box 를 호출할 수 있도록 해준다. 이것은 다음 처럼 사용하면 된다.

  • NMessageProvider 는 최상단 parent 즉, root 에 있어야 한다.

  • createDiscreteApi 를 사용하는 경우, useMessage 와는 동작이 다르다. 특히 provider 에 props 를 변경하는 경우, props 가 적용되지 않는다. doc 에 다음과 같은 이야기가 그것을 이야기 하는 듯 하다.

    from: https://www.naiveui.com/en-US/os-theme/components/discrete


    share config 가 필요하다면, 수동으로 해줘야 한다.

<template>
  <div>
    <div @click="onClickLogOut">
  </div>
</template>

<script>
import { useMessage } from 'naive-ui'

import api from '@/utils/api'

const _ = {
  name: 'LoginWidget',
  components: {
    NIcon,
    ExitIcon
  },
  data: function () {
    return {
      activeKey: null
    }
  },
  created: function(){
    this.message = useMessage();
  },
  methods: {
    async onClickLogOut() {
      this.message.warning(e.stack)
    }
  }
}

export default _
</script>
<style></style>
<template>
  <NMessageProvider placement="bottom">
    <LoginWidget>
    </LoginWidget>
  </NMessageProvider>
</template>

<script>
import LoginWidget from './LoginWidget'
import { NMessageProvider } from 'naive-ui'

const _ = {
  name: 'App',
  components: {
    LoginWidget,
    NMessageProvider
  },
  data: function () {
    return {}
  },
  methods: {}
}

export default _
</script>
<style></style>

[컴] 인프라 참고자표 from gruntwork

grunt / grunt work / best practice infra / infrastructure

인프라 참고자표 from gruntwork

gruntwork 라는 곳에서 대규모 아키텍쳐에 대한 best practice 를 공유한다. 항상 이것이 정답은 아닐 수 있으나 참고하면 좋은 구조일 듯 싶다.

[컴][툴] 알아두면 언젠가 쓸만한 툴, 2023-04-29

tool / tools / util/ utils

알아두면 언젠가 쓸만한 툴, 2023-04-29

See Also

  1. [파이썬] 알아두면 좋을 파이썬 프로젝트들
  2. 개발자가 알아두면 좋을 사이트
  3. 시스템 모니터링 툴들

[컴][알고리즘] Edit distance

fuzzy search / 검색 / 알고 /

Edit distance

edit distance 는 ‘Levenshtein distance’ 를 이야기 한다.

이 edit distance 가 어디에 쓰이냐면, fuzzy search 같은 대략적인 문자열을 매칭할떄 쓰인다.(Approximate string matching - Wikipedia) 이외에도 spell checker 나 OCR 등에서도 쓰인다고 한다.

이 Levenshtein distance 는 두 문자열을 비교해서 얼마나 다른가를 distance 로 표현한다. 이 distance 값은 2개의 문자열을 비교해서 ‘삽입’, ‘삭제’, ‘수정’ 이 얼마나 일어났는지를 확인해서 그 차이를 표현한 것이라 보면 된다.

‘삽입’, ‘삭제’, ‘수정’에 각각 같은 값을 줄 수도 있고, ’삽입’에 더 많은 값을 주거나 하는 등 각각의 비용은 다르게 처리할 수 있다. 예를 들어 ’삽입’ 1번 , ‘수정’ 1번이 필요한 경우, 이것을 각각 1의 비용을 산정해서 distance 2 로 표현할 수 있고, 삽입을 0.5로 비용을 산정해서 1.5 로 표현할 수도 있다.(0.5 + 1)

예시

길이가 같은 문자열 2개를 비교하는 예시를 한번 보자. 여기서는 ‘삽입’, ‘삭제’, ’수정’에 모두 1의 비용(cost) 이 발생한다고 보자.

A: hello my name is Tom B: hello my name is Gom

그럼 다음처럼 비교를 하게 된다.

  1. ‘h’ , ‘h’ -> 0
  2. ‘e’ , ‘e’ -> 0
  3. ‘l’ , ‘l’ -> 0
  4. ‘l’ , ‘l’ -> 0
  5. ‘o’ , ‘o’ -> 0
  6. ’ ’ , ’ ’ -> 0
  7. ‘m’ , ‘m’ -> 0
  8. ‘y’ , ‘y’ -> 0
  9. ’ ’ , ’ ’ -> 0
  10. ‘n’ , ‘n’ -> 0
  11. ‘a’ , ‘a’ -> 0
  12. ‘m’ , ‘m’ -> 0
  13. ‘e’ , ‘e’ -> 0
  14. ’ ’ , ’ ’ -> 0
  15. ‘i’ , ‘i’ -> 0
  16. ‘s’ , ‘s’ -> 0
  17. ’ ’ , ’ ’ -> 0
  18. ‘T’ , ‘G’ -> 1 // 수정
  19. ‘o’ , ‘o’ -> 0
  20. ‘m’ , ‘d’ -> 1 // 수정

그러면 두문자열에 대한 levenshtein distance 는 2이 된다. 다시말하면, A,B라는 2개의 문자열이 있을 때, A를 기준으로 삼으면, B는 2번의 수정을 거쳐서 A와 같아진다.라고 이야기할 수 있다.

참고로, 다른 길이 문자열은 길이가 다른 부분을 공백(’ ’)등으로 채워주면 된다. 그러면 그 부분에서는 distance 가 추가된다.

matrix

그런데 이것을 전체 string 에 대해서만 비교를 하지 않는다. 모든 case에 대해서 계산해서 행렬(matrix)를 만든다. matrix 가 있으면, backtracking 을 해서 비교대상 string 이 original string 으로 변경하기 위한 계산등을 할 수 있다.

아래 메트릭스를 보자. 이 메트릭스로 sittery 라는 문자열을 kitten으로 바꿀 수 있다.(sittery –> kitten)

가장 오른쪽 아래 cell 에서 시작한다.

현재의 cell 의 character가 다를 때

  • ’위’로 가면, insertion
  • ‘왼쪽’ 으로 가면 ‘deletion’
  • ‘대각선위’로 가면 ’substitution’(교체)

의 의미를 갖는다. 현재 cell 의 character가 같다면 그냥 대각선위로 움직인다.


“” s i t t e r y
“” 0 1 2 3 4 5 6 7
k 1 1 2 3 4 5 6 7
i 2 2 1 2 3 4 5 6
t 3 3 2 1 2 3 4 5
t 4 4 3 2 1 2 3 4
e 5 5 4 3 2 1 2 3
n 6 6 5 4 3 2 2 3

여기서 2가지 방법이 나온다. 오른쪽 아래에서 시작하면, 처음에 ‘대각선위’ 또는 ’왼쪽’으로 갈 수 있다.

여기서 그러면, 어디를 택하는 것이 맞을 것인가.

대체로 substitution 보다는 deletion, insertion 의 비용을 더 적게 잡는 듯 하다. 실제로도 위의 경우 substitution 으로 가면, 계속 character 를 변경해야 하지만, deletion 방향으로 움직이면, 그 후의 값들은 쭉 맞게 된다.

아래 그림에서도 보면, substitution 은 1, deletion, insertion 은 0.5 의 cost 를 준다.

관련 다른 알고리즘

  • Hamming distance - Wikipedia : 2개의 문자열이 같을 때 사용하는 알고리즘
  • Longest common subsequence :
    • 이 알고리즘이 git 등에서 revision 에 대한 diff 등을 얻어낼 때 사용된다.
    • 알고리즘 문제에도 많이 나오는데, 공통된 가장 긴 문자를 찾아내는 알고리즘이다.
    • 이 알고리즘으로 문자에 대한 삽입, 삭제에 대한 파악을 할 수 있다.

Reference

  1. Edit Distance. The Dynamic and The Recursive Approach | by Deboparna Banerjee | Medium
  2. 비슷한 명령어 추천은 어떻게 하는걸까?

슬래시 / slash / 슬래쉬

url 뒤에 ’/’를 붙이는 nginx 설정

현재 내 nginx 는 다음과 같다.

  • http://localhost/home : 404 error 가 난다.
  • http://localhost/home/ : http://localhost/home/index.html 을 호출해준다.

그래서 뒤에 ‘/’ 를 붙이는 설정을 해줘야 했다. 일단 내 경우는 다음의 답변이 적절한 듯 하다.

위의 답변에서는 file 일때는 ‘/’을 뒤에 붙이지 않고, file 이 아닌경우에’/’ 를 붙이게 된다.

추가로 http://localhost/home?q=test 의 경우도 ‘/’ 를 붙여서 http://localhost/home/?q=test로 만들어준다.

server {
   # ...
   if (!-f $request_filename) {
     rewrite [^/]$ $uri/ permanent;
   }
   location / {
      # CMS logic, e.g. try_files $uri $uri /index.php$request_uri;
   }
   # ...
}

sed -i ‘s,location / {,# add slash to the end of $uriif (!-f \(request_filename) {\n rewrite [^/]\) $uri/ permanent;}location / {,’ /etc/nginx/conf.d/default.conf

References

  1. Levenshtein distance - Wikipedia