Tarantool ์นดํŠธ๋ฆฌ์ง€์— ์‰ฝ๊ณ  ์ž์—ฐ์Šค๋Ÿฝ๊ฒŒ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ๋ฐฐํฌ(1๋ถ€)

Tarantool ์นดํŠธ๋ฆฌ์ง€์— ์‰ฝ๊ณ  ์ž์—ฐ์Šค๋Ÿฝ๊ฒŒ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ๋ฐฐํฌ(1๋ถ€)

์šฐ๋ฆฌ๋Š” ์ด๋ฏธ ์ด์•ผ๊ธฐํ–ˆ์Šต๋‹ˆ๋‹ค. ํƒ€๋ž€ํˆด ์นดํŠธ๋ฆฌ์ง€, ๋ถ„์‚ฐ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์„ ๊ฐœ๋ฐœํ•˜๊ณ  ํŒจํ‚ค์ง•ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์•„๋ฌด๊ฒƒ๋„ ๋‚จ์ง€ ์•Š์•˜์Šต๋‹ˆ๋‹ค. ์ด๋Ÿฌํ•œ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์„ ๋ฐฐํฌํ•˜๊ณ  ๊ด€๋ฆฌํ•˜๋Š” ๋ฐฉ๋ฒ•์„ ์•Œ์•„๋ณด์„ธ์š”. ๊ฑฑ์ •ํ•˜์ง€ ๋งˆ์„ธ์š”. ์šฐ๋ฆฌ๋Š” ๋ชจ๋“  ๊ฒƒ์„ ๊ณ ๋ คํ–ˆ์Šต๋‹ˆ๋‹ค! ์šฐ๋ฆฌ๋Š” Tarantool Cartridge ์ž‘์—…์— ๋Œ€ํ•œ ๋ชจ๋“  ๋ชจ๋ฒ” ์‚ฌ๋ก€๋ฅผ ๋ชจ์•„์„œ ์ž‘์„ฑํ–ˆ์Šต๋‹ˆ๋‹ค. ๊ฐ€๋Šฅํ•œ ์—ญํ• ํŒจํ‚ค์ง€๋ฅผ ์„œ๋ฒ„๋กœ ๋ถ„ํ•ดํ•˜๊ณ , ์ธ์Šคํ„ด์Šค๋ฅผ ์‹œ์ž‘ํ•˜๊ณ , ํด๋Ÿฌ์Šคํ„ฐ๋กœ ํ†ตํ•ฉํ•˜๊ณ , ์ธ์ฆ์„ ๊ตฌ์„ฑํ•˜๊ณ , vshard๋ฅผ ๋ถ€ํŠธ์ŠคํŠธ๋žฉํ•˜๊ณ , ์ž๋™ ์žฅ์•  ์กฐ์น˜๋ฅผ ํ™œ์„ฑํ™”ํ•˜๊ณ , ํด๋Ÿฌ์Šคํ„ฐ ๊ตฌ์„ฑ์„ ํŒจ์น˜ํ•ฉ๋‹ˆ๋‹ค.

ํฅ๋ฏธ๋กœ์šด? ๊ทธ๋Ÿฐ ๋‹ค์Œ ์ปท ์•„๋ž˜์— ๋ฌผ์–ด ๋ณด๋ฉด ๋ชจ๋“  ๊ฒƒ์„ ๋งํ•˜๊ณ  ๋ณด์—ฌ์ค„ ๊ฒƒ์ž…๋‹ˆ๋‹ค.

์˜ˆ๋ถ€ํ„ฐ ์‹œ์ž‘ํ•ด ๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค.

์šฐ๋ฆฌ๋Š” ์—ญํ• ์˜ ๊ธฐ๋Šฅ ์ค‘ ์ผ๋ถ€๋งŒ ๋‹ค๋ฃฐ ๊ฒƒ์ž…๋‹ˆ๋‹ค. ๋ชจ๋“  ๊ธฐ๋Šฅ๊ณผ ์ž…๋ ฅ ๋งค๊ฐœ๋ณ€์ˆ˜์— ๋Œ€ํ•œ ์ „์ฒด ์„ค๋ช…์€ ์–ธ์ œ๋“ ์ง€ ๋‹ค์Œ์—์„œ ํ™•์ธํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์„ ์  ์„œ๋ฅ˜ ๋น„์น˜. ํ•˜์ง€๋งŒ ๋ฐฑ ๋ฒˆ ๋ณด๋Š” ๊ฒƒ๋ณด๋‹ค ํ•œ ๋ฒˆ ์‹œ๋„ํ•ด ๋ณด๋Š” ๊ฒƒ์ด ๋” ๋‚ซ๊ธฐ ๋•Œ๋ฌธ์— ์ž‘์€ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์„ ๋ฐฐํฌํ•ด ๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค.

Tarantool ์นดํŠธ๋ฆฌ์ง€์—๋Š” ์ง€๋„ ์‹œ๊ฐ„ ์€ํ–‰ ๊ณ ๊ฐ ๋ฐ ๊ณ„์ขŒ์— ๋Œ€ํ•œ ์ •๋ณด๋ฅผ ์ €์žฅํ•˜๊ณ  HTTP๋ฅผ ํ†ตํ•ด ๋ฐ์ดํ„ฐ๋ฅผ ๊ด€๋ฆฌํ•˜๊ธฐ ์œ„ํ•œ API๋ฅผ ์ œ๊ณตํ•˜๋Š” ์ž‘์€ ์นดํŠธ๋ฆฌ์ง€ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์„ ์ƒ์„ฑํ•ฉ๋‹ˆ๋‹ค. ์ด๋ฅผ ์œ„ํ•ด ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์€ ๋‘ ๊ฐ€์ง€ ๊ฐ€๋Šฅํ•œ ์—ญํ• ์„ ์„ค๋ช…ํ•ฉ๋‹ˆ๋‹ค. api ะธ storage์ธ์Šคํ„ด์Šค์— ํ• ๋‹นํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

์นดํŠธ๋ฆฌ์ง€ ์ž์ฒด๋Š” ํ”„๋กœ์„ธ์Šค๋ฅผ ์‹œ์ž‘ํ•˜๋Š” ๋ฐฉ๋ฒ•์— ๋Œ€ํ•ด ์•„๋ฌด ๋ง๋„ ํ•˜์ง€ ์•Š์œผ๋ฉฐ ์ด๋ฏธ ์‹คํ–‰ ์ค‘์ธ ์ธ์Šคํ„ด์Šค๋ฅผ ๊ตฌ์„ฑํ•˜๋Š” ๊ธฐ๋Šฅ๋งŒ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค. ๊ตฌ์„ฑ ํŒŒ์ผ ๋ถ„ํ•ด, ์„œ๋น„์Šค ์‹œ์ž‘, ํ† ํด๋กœ์ง€ ์„ค์ • ๋“ฑ ๋‚˜๋จธ์ง€ ์ž‘์—…์€ ์‚ฌ์šฉ์ž๊ฐ€ ์ง์ ‘ ์ˆ˜ํ–‰ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ํ•˜์ง€๋งŒ ์šฐ๋ฆฌ๋Š” ์ด ๋ชจ๋“  ์ž‘์—…์„ ์ˆ˜ํ–‰ํ•˜์ง€ ์•Š์„ ๊ฒƒ์ด๋ฉฐ Ansible์ด ์šฐ๋ฆฌ๋ฅผ ์œ„ํ•ด ์ด๋ฅผ ์ˆ˜ํ–‰ํ•  ๊ฒƒ์ž…๋‹ˆ๋‹ค.

์ฆ์„œ์—์„œ ํ–‰๋™์œผ๋กœ

์ด์ œ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์„ ๋‘ ๊ฐœ์˜ ๊ฐ€์ƒ ๋จธ์‹ ์— ๋ฐฐํฌํ•˜๊ณ  ๊ฐ„๋‹จํ•œ ํ† ํด๋กœ์ง€๋ฅผ ์„ค์ •ํ•ด ๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค.

  • ๋ณต์ œ๋ณธ app-1 ์—ญํ• ์„ ํ•˜๊ฒŒ ๋  ๊ฒƒ์ด๋‹ค api์—ญํ• ์„ ํฌํ•จํ•˜๋Š” vshard-router. ์—ฌ๊ธฐ์—๋Š” ์ธ์Šคํ„ด์Šค๊ฐ€ ํ•˜๋‚˜๋งŒ ์žˆ์Šต๋‹ˆ๋‹ค.
  • ๋ณต์ œ์„ธํŠธ storage-1 ์—ญํ• ์„ ๊ตฌํ˜„ํ•œ๋‹ค storage (๊ทธ๋ฆฌ๊ณ  ๋™์‹œ์— vshard-storage), ์—ฌ๊ธฐ์„œ๋Š” ์„œ๋กœ ๋‹ค๋ฅธ ๋จธ์‹ ์˜ ๋‘ ์ธ์Šคํ„ด์Šค๋ฅผ ์ถ”๊ฐ€ํ•ฉ๋‹ˆ๋‹ค.

Tarantool ์นดํŠธ๋ฆฌ์ง€์— ์‰ฝ๊ณ  ์ž์—ฐ์Šค๋Ÿฝ๊ฒŒ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ๋ฐฐํฌ(1๋ถ€)

์˜ˆ์ œ๋ฅผ ์‹คํ–‰ํ•˜๋ ค๋ฉด ๋‹ค์Œ์ด ํ•„์š”ํ•ฉ๋‹ˆ๋‹ค. ๋ฐฉ๋ž‘์ž ะธ ์ฑ…์ž„๊ฐ์žˆ๋Š” (๋ฒ„์ „ 2.8 ์ด์ƒ).

์—ญํ•  ์ž์ฒด๋Š” ์•ค์„œ๋ธ” ๊ฐค๋Ÿญ์‹œ. ์ด๋Š” ์ž‘์—…์„ ๊ณต์œ ํ•˜๊ณ  ๊ธฐ์„ฑ ์—ญํ• ์„ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋Š” ์ €์žฅ์†Œ์ž…๋‹ˆ๋‹ค.

๋‹ค์Œ ์˜ˆ์‹œ๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์ €์žฅ์†Œ๋ฅผ ๋ณต์ œํ•˜์„ธ์š”.

$ git clone https://github.com/dokshina/deploy-tarantool-cartridge-app.git
$ cd deploy-tarantool-cartridge-app && git checkout 1.0.0

์šฐ๋ฆฌ๋Š” ๊ฐ€์ƒ ๋จธ์‹ ์„ ํ‚ค์›๋‹ˆ๋‹ค:

$ vagrant up

Tarantool Cartridge ansible ์—ญํ• ์„ ์„ค์น˜ํ•ฉ๋‹ˆ๋‹ค.

$ ansible-galaxy install tarantool.cartridge,1.0.1

์„ค์น˜๋œ ์—ญํ• ์„ ์‹คํ–‰ํ•ฉ๋‹ˆ๋‹ค.

$ ansible-playbook -i hosts.yml playbook.yml

ํ”Œ๋ ˆ์ด๋ถ ์‹คํ–‰์ด ๋๋‚˜๊ธฐ๋ฅผ ๊ธฐ๋‹ค๋ฆฌ๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค. http://localhost:8181/admin/cluster/dashboard ๊ฒฐ๊ณผ๋ฅผ ์ฆ๊ธฐ์‹ญ์‹œ์˜ค.

Tarantool ์นดํŠธ๋ฆฌ์ง€์— ์‰ฝ๊ณ  ์ž์—ฐ์Šค๋Ÿฝ๊ฒŒ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ๋ฐฐํฌ(1๋ถ€)

๋ฐ์ดํ„ฐ๋ฅผ ์Ÿ์•„๋ถ€์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๋ฉ‹์ง€์ฃ ?

์ด์ œ ์ด ์ž‘์—…์„ ์ˆ˜ํ–‰ํ•˜๋Š” ๋ฐฉ๋ฒ•์„ ์•Œ์•„๋ณด๊ณ  ๋™์‹œ์— ํ† ํด๋กœ์ง€์— ๋‹ค๋ฅธ ๋ณต์ œ๋ณธ ์„ธํŠธ๋ฅผ ์ถ”๊ฐ€ํ•ด ๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค.

์šฐ๋ฆฌ๋Š” ์ดํ•ดํ•˜๊ธฐ ์‹œ์ž‘ํ•ฉ๋‹ˆ๋‹ค

๊ทธ๋ž˜์„œ ๋ฌด์Šจ ์ผ์ด ์ผ์–ด๋‚ฌ๋‚˜์š”?

์šฐ๋ฆฌ๋Š” ๋‘ ๊ฐœ์˜ VM์„ ์ค€๋น„ํ•˜๊ณ  ํด๋Ÿฌ์Šคํ„ฐ๋ฅผ ์„ค์ •ํ•˜๋Š” Ansible ํ”Œ๋ ˆ์ด๋ถ์„ ์‹คํ–‰ํ–ˆ์Šต๋‹ˆ๋‹ค. ํŒŒ์ผ ๋‚ด์šฉ์„ ์‚ดํŽด๋ณด์ž playbook.yml:

---
- name: Deploy my Tarantool Cartridge app
  hosts: all
  become: true
  become_user: root
  tasks:
  - name: Import Tarantool Cartridge role
    import_role:
      name: tarantool.cartridge

์—ฌ๊ธฐ์„œ๋Š” ํฅ๋ฏธ๋กœ์šด ์ผ์ด ์ผ์–ด๋‚˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ์šฐ๋ฆฌ๋Š” ansible-role์„ ์‹œ์ž‘ํ•ฉ๋‹ˆ๋‹ค. tarantool.cartridge.

๊ฐ€์žฅ ์ค‘์š”ํ•œ ๋ชจ๋“  ๊ฒƒ(์ฆ‰, ํด๋Ÿฌ์Šคํ„ฐ ๊ตฌ์„ฑ)์€ ๋‹ค์Œ ์œ„์น˜์— ์žˆ์Šต๋‹ˆ๋‹ค. ๋ชฉ๋ก-ํŒŒ์ผ hosts.yml:

---
all:
  vars:
    # common cluster variables
    cartridge_app_name: getting-started-app
    cartridge_package_path: ./getting-started-app-1.0.0-0.rpm  # path to package

    cartridge_cluster_cookie: app-default-cookie  # cluster cookie

    # common ssh options
    ansible_ssh_private_key_file: ~/.vagrant.d/insecure_private_key
    ansible_ssh_common_args: '-o IdentitiesOnly=yes -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no'

  # INSTANCES
  hosts:
    storage-1:
      config:
        advertise_uri: '172.19.0.2:3301'
        http_port: 8181

    app-1:
      config:
        advertise_uri: '172.19.0.3:3301'
        http_port: 8182

    storage-1-replica:
      config:
        advertise_uri: '172.19.0.3:3302'
        http_port: 8183

  children:
    # GROUP INSTANCES BY MACHINES
    host1:
      vars:
        # first machine connection options
        ansible_host: 172.19.0.2
        ansible_user: vagrant

      hosts:  # instances to be started on the first machine
        storage-1:

    host2:
      vars:
        # second machine connection options
        ansible_host: 172.19.0.3
        ansible_user: vagrant

      hosts:  # instances to be started on the second machine
        app-1:
        storage-1-replica:

    # GROUP INSTANCES BY REPLICA SETS
    replicaset_app_1:
      vars:  # replica set configuration
        replicaset_alias: app-1
        failover_priority:
          - app-1  # leader
        roles:
          - 'api'

      hosts:  # replica set instances
        app-1:

    replicaset_storage_1:
      vars:  # replica set configuration
        replicaset_alias: storage-1
        weight: 3
        failover_priority:
          - storage-1  # leader
          - storage-1-replica
        roles:
          - 'storage'

      hosts:   # replica set instances
        storage-1:
        storage-1-replica:

์šฐ๋ฆฌ์—๊ฒŒ ํ•„์š”ํ•œ ๊ฒƒ์€ ์ด ํŒŒ์ผ์˜ ๋‚ด์šฉ์„ ๋ณ€๊ฒฝํ•˜์—ฌ ์ธ์Šคํ„ด์Šค์™€ ๋ณต์ œ๋ณธ ์„ธํŠธ๋ฅผ ๊ด€๋ฆฌํ•˜๋Š” ๋ฐฉ๋ฒ•์„ ๋ฐฐ์šฐ๋Š” ๊ฒƒ๋ฟ์ž…๋‹ˆ๋‹ค. ๋‹ค์Œ์œผ๋กœ ์ƒˆ๋กœ์šด ์„น์…˜์„ ์ถ”๊ฐ€ํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค. ์–ด๋””์— ์ถ”๊ฐ€ํ•ด์•ผ ํ• ์ง€ ํ˜ผ๋™ํ•˜์ง€ ์•Š์œผ๋ ค๋ฉด ์ด ํŒŒ์ผ์˜ ์ตœ์ข… ๋ฒ„์ „์„ ์‚ดํŽด๋ณด์„ธ์š”. hosts.updated.yml, ์ด๋Š” ์˜ˆ์ œ ์ €์žฅ์†Œ์— ์žˆ์Šต๋‹ˆ๋‹ค.

์ธ์Šคํ„ด์Šค ๊ด€๋ฆฌ

Ansible์˜ ๊ด€์ ์—์„œ ๊ฐ ์ธ์Šคํ„ด์Šค๋Š” ํ˜ธ์ŠคํŠธ์ž…๋‹ˆ๋‹ค(์ฒ  ์„œ๋ฒ„์™€ ํ˜ผ๋™ํ•˜์ง€ ๋งˆ์‹ญ์‹œ์˜ค). Ansible์ด ๊ด€๋ฆฌํ•  ์ธํ”„๋ผ ๋…ธ๋“œ์ž…๋‹ˆ๋‹ค. ๊ฐ ํ˜ธ์ŠคํŠธ์— ๋Œ€ํ•ด ์—ฐ๊ฒฐ ๋งค๊ฐœ๋ณ€์ˆ˜(์˜ˆ: ansible_host ะธ ansible_user) ๋ฐ ์ธ์Šคํ„ด์Šค ๊ตฌ์„ฑ๋„ ๋งˆ์ฐฌ๊ฐ€์ง€์ž…๋‹ˆ๋‹ค. ์ธ์Šคํ„ด์Šค์— ๋Œ€ํ•œ ์„ค๋ช…์€ ์„น์…˜์— ์žˆ์Šต๋‹ˆ๋‹ค. hosts.

์ธ์Šคํ„ด์Šค ๊ตฌ์„ฑ์„ ๊ณ ๋ คํ•˜์‹ญ์‹œ์˜ค. storage-1:

all:
  vars:
    ...

  # INSTANCES
  hosts:
    storage-1:
      config:
        advertise_uri: '172.19.0.2:3301'
        http_port: 8181

  ...

๋ณ€์ˆ˜์—์„œ config ์ธ์Šคํ„ด์Šค ๋งค๊ฐœ๋ณ€์ˆ˜๋ฅผ ์ง€์ •ํ–ˆ์Šต๋‹ˆ๋‹ค. advertise URI ะธ HTTP port.
๋‹ค์Œ์€ ์ธ์Šคํ„ด์Šค ๋งค๊ฐœ๋ณ€์ˆ˜์ž…๋‹ˆ๋‹ค. app-1 ะธ storage-1-replica.

๊ฐ ์ธ์Šคํ„ด์Šค์— ๋Œ€ํ•œ ์—ฐ๊ฒฐ ๋งค๊ฐœ๋ณ€์ˆ˜๋ฅผ Ansible์— ์•Œ๋ ค์ฃผ์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ์ธ์Šคํ„ด์Šค๋ฅผ ๊ฐ€์ƒ ๋จธ์‹  ๊ทธ๋ฃน์œผ๋กœ ๊ทธ๋ฃนํ™”ํ•˜๋Š” ๊ฒƒ์ด ๋…ผ๋ฆฌ์ ์ธ ๊ฒƒ ๊ฐ™์Šต๋‹ˆ๋‹ค. ์ด๋ฅผ ์œ„ํ•ด ์ธ์Šคํ„ด์Šค๊ฐ€ ๊ทธ๋ฃน์œผ๋กœ ๊ฒฐํ•ฉ๋ฉ๋‹ˆ๋‹ค. host1 ะธ host2๋ฐ ์„น์…˜์˜ ๊ฐ ๊ทธ๋ฃน์—์„œ vars ๊ฐ€์น˜ ansible_host ะธ ansible_user ํ•˜๋‚˜์˜ ๊ฐ€์ƒ ๋จธ์‹ ์— ๋Œ€ํ•ด. ๊ทธ๋ฆฌ๊ณ  ์„น์…˜์—์„œ๋Š” hosts - ์ด ๊ทธ๋ฃน์— ํฌํ•จ๋œ ํ˜ธ์ŠคํŠธ(์ธ์Šคํ„ด์Šค):

all:
  vars:
    ...
  hosts:
    ...
  children:
    # GROUP INSTANCES BY MACHINES
    host1:
      vars:
        # first machine connection options
        ansible_host: 172.19.0.2
        ansible_user: vagrant
       hosts:  # instances to be started on the first machine
        storage-1:

     host2:
      vars:
        # second machine connection options
        ansible_host: 172.19.0.3
        ansible_user: vagrant
       hosts:  # instances to be started on the second machine
        app-1:
        storage-1-replica:

์šฐ๋ฆฌ๋Š” ๋ณ€ํ•˜๊ธฐ ์‹œ์ž‘ํ•œ๋‹ค hosts.yml. ๋‘ ๊ฐœ์˜ ์ธ์Šคํ„ด์Šค๋ฅผ ๋” ์ถ”๊ฐ€ํ•ด ๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค. storage-2-replica ์ฒซ ๋ฒˆ์งธ ๊ฐ€์ƒ ๋จธ์‹ ์—์„œ storage-2 ๋‘ ๋ฒˆ์งธ:

all:
  vars:
    ...

  # INSTANCES
  hosts:
    ...
    storage-2:  # <==
      config:
        advertise_uri: '172.19.0.3:3303'
        http_port: 8184

    storage-2-replica:  # <==
      config:
        advertise_uri: '172.19.0.2:3302'
        http_port: 8185

  children:
    # GROUP INSTANCES BY MACHINES
    host1:
      vars:
        ...
      hosts:  # instances to be started on the first machine
        storage-1:
        storage-2-replica:  # <==

    host2:
      vars:
        ...
      hosts:  # instances to be started on the second machine
        app-1:
        storage-1-replica:
        storage-2:  # <==
  ...

Ansible ํ”Œ๋ ˆ์ด๋ถ์„ ์‹คํ–‰ํ•ฉ๋‹ˆ๋‹ค.

$ ansible-playbook -i hosts.yml 
                   --limit storage-2,storage-2-replica 
                   playbook.yml

์˜ต์…˜์— ์ฃผ๋ชฉํ•˜์„ธ์š” --limit. ๊ฐ ํด๋Ÿฌ์Šคํ„ฐ ์ธ์Šคํ„ด์Šค๋Š” Ansible ์šฉ์–ด๋กœ ํ˜ธ์ŠคํŠธ์ด๋ฏ€๋กœ ํ”Œ๋ ˆ์ด๋ถ์„ ์‹คํ–‰ํ•  ๋•Œ ๊ตฌ์„ฑํ•ด์•ผ ํ•˜๋Š” ์ธ์Šคํ„ด์Šค๋ฅผ ๋ช…์‹œ์ ์œผ๋กœ ์ง€์ •ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

์›น UI๋กœ ๋Œ์•„๊ฐ€๊ธฐ http://localhost:8181/admin/cluster/dashboard ์ƒˆ๋กœ์šด ์ธ์Šคํ„ด์Šค๋ฅผ ๊ด€์ฐฐํ•˜์„ธ์š”.

Tarantool ์นดํŠธ๋ฆฌ์ง€์— ์‰ฝ๊ณ  ์ž์—ฐ์Šค๋Ÿฝ๊ฒŒ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ๋ฐฐํฌ(1๋ถ€)

์šฐ๋ฆฌ๋Š” ์„ฑ๊ณต์— ์•ˆ์ฃผํ•˜์ง€ ์•Š๊ณ  ํ† ํด๋กœ์ง€ ์ œ์–ด๋ฅผ ๋งˆ์Šคํ„ฐํ•  ๊ฒƒ์ž…๋‹ˆ๋‹ค.

ํ† ํด๋กœ์ง€ ๊ด€๋ฆฌ

์ƒˆ ์ธ์Šคํ„ด์Šค๋ฅผ ๋ณต์ œ๋ณธ ์„ธํŠธ๋กœ ๋ณ‘ํ•ฉํ•ด ๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค. storage-2. ์ƒˆ ๊ทธ๋ฃน์„ ์ถ”๊ฐ€ํ•ด ๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค. replicaset_storage_2 ๋ณ€์ˆ˜์—์„œ ๋ณต์ œ๋ณธ ์„ธํŠธ์˜ ๋งค๊ฐœ๋ณ€์ˆ˜๋ฅผ ๋‹ค์Œ๊ณผ ์œ ์‚ฌํ•˜๊ฒŒ ์„ค๋ช…ํ•ฉ๋‹ˆ๋‹ค. replicaset_storage_1. ์„น์…˜์—์„œ hosts ์ด ๊ทธ๋ฃน(์ฆ‰, ๋ณต์ œ๋ณธ ์„ธํŠธ)์— ํฌํ•จ๋  ์ธ์Šคํ„ด์Šค๋ฅผ ์ง€์ •ํ•ฉ๋‹ˆ๋‹ค.

---
all:
  vars:
    ...
  hosts:
    ...
  children:
    ...
    # GROUP INSTANCES BY REPLICA SETS
    ...
    replicaset_storage_2:  # <==
      vars:  # replicaset configuration
        replicaset_alias: storage-2
        weight: 2
        failover_priority:
          - storage-2
          - storage-2-replica
        roles:
          - 'storage'

      hosts:   # replicaset instances
        storage-2:
        storage-2-replica:

ํ”Œ๋ ˆ์ด๋ถ์„ ๋‹ค์‹œ ์‹œ์ž‘ํ•ด ๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค.

$ ansible-playbook -i hosts.yml 
                   --limit replicaset_storage_2 
                   --tags cartridge-replicasets 
                   playbook.yml

์˜ต์…˜๋ณ„ --limit ์ด๋ฒˆ์—๋Š” ๋ณต์ œ ์„ธํŠธ์— ํ•ด๋‹นํ•˜๋Š” ๊ทธ๋ฃน์˜ ์ด๋ฆ„์„ ์ „๋‹ฌํ–ˆ์Šต๋‹ˆ๋‹ค.

์˜ต์…˜์„ ๊ณ ๋ คํ•˜์‹ญ์‹œ์˜ค tags.

์šฐ๋ฆฌ์˜ ์—ญํ• ์€ ๋‹ค์Œ ํƒœ๊ทธ๋กœ ํ‘œ์‹œ๋œ ๋‹ค์–‘ํ•œ ์ž‘์—…์„ ์ˆœ์ฐจ์ ์œผ๋กœ ์ˆ˜ํ–‰ํ•ฉ๋‹ˆ๋‹ค.

  • cartridge-instances: ์ธ์Šคํ„ด์Šค ๊ด€๋ฆฌ(๊ตฌ์„ฑ, ํšŒ์›๊ฐ€์ž…);
  • cartridge-replicasets: ํ† ํด๋กœ์ง€ ๊ด€๋ฆฌ(๋ณต์ œ๋ณธ ๊ด€๋ฆฌ ๋ฐ ํด๋Ÿฌ์Šคํ„ฐ์—์„œ ์ธ์Šคํ„ด์Šค ์˜๊ตฌ ์ œ๊ฑฐ(์ถ”๋ฐฉ))
  • cartridge-config: ๊ธฐํƒ€ ํด๋Ÿฌ์Šคํ„ฐ ๋งค๊ฐœ๋ณ€์ˆ˜(vshard ๋ถ€ํŠธ์ŠคํŠธ๋ž˜ํ•‘, ์ž๋™ ์žฅ์•  ์กฐ์น˜ ๋ชจ๋“œ, ์ธ์ฆ ๋งค๊ฐœ๋ณ€์ˆ˜ ๋ฐ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ๊ตฌ์„ฑ)๋ฅผ ๊ด€๋ฆฌํ•ฉ๋‹ˆ๋‹ค.

์ˆ˜ํ–‰ํ•˜๋ ค๋Š” ์ž‘์—… ๋ถ€๋ถ„์„ ๋ช…์‹œ์ ์œผ๋กœ ์ง€์ •ํ•  ์ˆ˜ ์žˆ์œผ๋ฉฐ, ๊ทธ๋Ÿฌ๋ฉด ํ•ด๋‹น ์—ญํ• ์€ ๋‚˜๋จธ์ง€ ์ž‘์—…์„ ๊ฑด๋„ˆ๋œ๋‹ˆ๋‹ค. ์šฐ๋ฆฌ์˜ ๊ฒฝ์šฐ์—๋Š” ํ† ํด๋กœ์ง€๋กœ๋งŒ ์ž‘์—…ํ•˜๊ธฐ๋ฅผ ์›ํ•˜๋ฏ€๋กœ ๋‹ค์Œ๊ณผ ๊ฐ™์ด ์ง€์ •ํ–ˆ์Šต๋‹ˆ๋‹ค. cartridge-replicasets.

์šฐ๋ฆฌ์˜ ๋…ธ๋ ฅ์˜ ๊ฒฐ๊ณผ๋ฅผ ํ‰๊ฐ€ํ•ด ๋ด…์‹œ๋‹ค. ์ƒˆ๋กœ์šด ๋ณต์ œ ์„ธํŠธ ์ฐพ๊ธฐ http://localhost:8181/admin/cluster/dashboard.

Tarantool ์นดํŠธ๋ฆฌ์ง€์— ์‰ฝ๊ณ  ์ž์—ฐ์Šค๋Ÿฝ๊ฒŒ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ๋ฐฐํฌ(1๋ถ€)

๋งŒ์„ธ!

์ธ์Šคํ„ด์Šค์™€ ๋ณต์ œ๋ณธ ์„ธํŠธ๋ฅผ ์žฌ๊ตฌ์„ฑํ•˜์—ฌ ์‹คํ—˜ํ•˜๊ณ  ํด๋Ÿฌ์Šคํ„ฐ ํ† ํด๋กœ์ง€๊ฐ€ ์–ด๋–ป๊ฒŒ ๋ณ€๊ฒฝ๋˜๋Š”์ง€ ํ™•์ธํ•˜์„ธ์š”. ์˜ˆ๋ฅผ ๋“ค์–ด, ๋‹ค์–‘ํ•œ ์šด์˜ ์‹œ๋‚˜๋ฆฌ์˜ค๋ฅผ ์‹œ๋„ํ•ด ๋ณผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๋กค๋ง ์—…๋ฐ์ดํŠธ ๋˜๋Š” ์ฆ๊ฐ€ memtx_memory. ํ•ด๋‹น ์—ญํ• ์€ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์˜ ๊ฐ€๋™ ์ค‘์ง€ ์‹œ๊ฐ„์„ ์ค„์ด๊ธฐ ์œ„ํ•ด ์ธ์Šคํ„ด์Šค๋ฅผ ๋‹ค์‹œ ์‹œ์ž‘ํ•˜์ง€ ์•Š๊ณ  ์ด ์ž‘์—…์„ ์ˆ˜ํ–‰ํ•˜๋ ค๊ณ  ํ•ฉ๋‹ˆ๋‹ค.

๋‹ฌ๋ฆฌ๋Š” ๊ฒƒ์„ ์žŠ์ง€ ๋งˆ์„ธ์š” vagrant halt์ž‘์—…์ด ๋๋‚˜๋ฉด VM์„ ์ค‘์ง€ํ•ฉ๋‹ˆ๋‹ค.

ํ›„๋“œ ์•„๋ž˜์—๋Š” ๋ฌด์—‡์ด ์žˆ์Šต๋‹ˆ๊นŒ?

์—ฌ๊ธฐ์„œ๋Š” ์‹คํ—˜ ์ค‘ ansible ์—ญํ•  ๋‚ด๋ถ€์—์„œ ๋ฐœ์ƒํ•œ ์ผ์— ๋Œ€ํ•ด ์ž์„ธํžˆ ์„ค๋ช…ํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค.

์นดํŠธ๋ฆฌ์ง€ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ๋ฐฐํฌ๋ฅผ ๋‹จ๊ณ„๋ณ„๋กœ ์‚ดํŽด๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค.

ํŒจํ‚ค์ง€ ์„ค์น˜ ๋ฐ ์ธ์Šคํ„ด์Šค ์‹œ์ž‘

๋จผ์ € ํŒจํ‚ค์ง€๋ฅผ ์„œ๋ฒ„์— ์ „๋‹ฌํ•˜๊ณ  ์„ค์น˜ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ์ด์ œ ํ•ด๋‹น ์—ญํ• ์€ RPM ๋ฐ DEB ํŒจํ‚ค์ง€์™€ ํ•จ๊ป˜ ์ž‘๋™ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

๋‹ค์Œ์œผ๋กœ ์ธ์Šคํ„ด์Šค๋ฅผ ์‹œ์ž‘ํ•ฉ๋‹ˆ๋‹ค. ์—ฌ๊ธฐ์—์„œ๋Š” ๋ชจ๋“  ๊ฒƒ์ด ๋งค์šฐ ๊ฐ„๋‹จํ•ฉ๋‹ˆ๋‹ค. ๊ฐ ์ธ์Šคํ„ด์Šค๋Š” ๋ณ„๋„์ž…๋‹ˆ๋‹ค. systemd-์„œ๋น„์Šค. ๋‚˜๋Š” ์˜ˆ์— ๋Œ€ํ•ด ์ด์•ผ๊ธฐํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค.

$ systemctl start myapp@storage-1

์ด ๋ช…๋ น์€ ์ธ์Šคํ„ด์Šค๋ฅผ ์‹œ์ž‘ํ•ฉ๋‹ˆ๋‹ค storage-1 ์• ํ”Œ ๋ฆฌ์ผ€์ด์…˜ myapp. ์‹œ์ž‘๋œ ์ธ์Šคํ„ด์Šค๋Š” ํ•ด๋‹น ์ธ์Šคํ„ด์Šค๋ฅผ ์ฐพ์Šต๋‹ˆ๋‹ค. ๊ตฌ์„ฑ ะฒ /etc/tarantool/conf.d/. ์ธ์Šคํ„ด์Šค ๋กœ๊ทธ๋Š” ๋‹ค์Œ์„ ์‚ฌ์šฉํ•˜์—ฌ ๋ณผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. journald.

์œ ๋‹› ํŒŒ์ผ /etc/systemd/system/[email protected] ์‹œ์Šคํ…œ ์„œ๋น„์Šค์˜ ๊ฒฝ์šฐ ํŒจํ‚ค์ง€์™€ ํ•จ๊ป˜ ์ œ๊ณต๋ฉ๋‹ˆ๋‹ค.

Ansible์—๋Š” ํŒจํ‚ค์ง€ ์„ค์น˜ ๋ฐ ์‹œ์Šคํ…œ ์„œ๋น„์Šค ๊ด€๋ฆฌ๋ฅผ ์œ„ํ•œ ๋‚ด์žฅ ๋ชจ๋“ˆ์ด ์žˆ์ง€๋งŒ ์—ฌ๊ธฐ์„œ๋Š” ์ƒˆ๋กœ์šด ๊ฒƒ์„ ๋ฐœ๋ช…ํ•˜์ง€ ์•Š์•˜์Šต๋‹ˆ๋‹ค.

ํด๋Ÿฌ์Šคํ„ฐ ํ† ํด๋กœ์ง€ ๊ตฌ์„ฑ

๊ทธ๋ฆฌ๊ณ  ์—ฌ๊ธฐ์„œ ๊ฐ€์žฅ ํฅ๋ฏธ๋กœ์šด ์ผ์ด ์‹œ์ž‘๋ฉ๋‹ˆ๋‹ค. ๋™์˜ํ•ฉ๋‹ˆ๋‹ค. ํŒจํ‚ค์ง€๋ฅผ ์„ค์น˜ํ•˜๊ณ  ์‹คํ–‰ํ•˜๊ธฐ ์œ„ํ•ด ํŠน๋ณ„ํ•œ ansible ์—ญํ• ์„ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์€ ์ด์ƒํ•  ๊ฒƒ์ž…๋‹ˆ๋‹ค. systemd-์„œ๋น„์Šค.

ํด๋Ÿฌ์Šคํ„ฐ๋ฅผ ์ˆ˜๋™์œผ๋กœ ์„ค์ •ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

  • ์ฒซ ๋ฒˆ์งธ ์˜ต์…˜: ์›น UI๋ฅผ ์—ด๊ณ  ๋ฒ„ํŠผ์„ ํด๋ฆญํ•ฉ๋‹ˆ๋‹ค. ์—ฌ๋Ÿฌ ์ธ์Šคํ„ด์Šค๋ฅผ ํ•œ ๋ฒˆ ์‹œ์ž‘ํ•˜๋Š” ๊ฒฝ์šฐ ๋งค์šฐ ์ ํ•ฉํ•ฉ๋‹ˆ๋‹ค.
  • ๋‘ ๋ฒˆ์งธ ์˜ต์…˜: GraphQl API๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์—ฌ๊ธฐ์—์„œ๋Š” Python์œผ๋กœ ์Šคํฌ๋ฆฝํŠธ ์ž‘์„ฑ๊ณผ ๊ฐ™์€ ์ž‘์—…์„ ์ด๋ฏธ ์ž๋™ํ™”ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
  • ์„ธ ๋ฒˆ์งธ ์˜ต์…˜(์ •์‹ ์ด ๊ฐ•ํ•œ ๊ฒฝ์šฐ): ์„œ๋ฒ„๋กœ ์ด๋™ํ•˜์—ฌ ๋‹ค์Œ์„ ์‚ฌ์šฉํ•˜์—ฌ ์ธ์Šคํ„ด์Šค ์ค‘ ํ•˜๋‚˜์— ์—ฐ๊ฒฐํ•ฉ๋‹ˆ๋‹ค. tarantoolctl connect Lua ๋ชจ๋“ˆ์„ ์‚ฌ์šฉํ•˜์—ฌ ํ•„์š”ํ•œ ๋ชจ๋“  ์กฐ์ž‘์„ ์ˆ˜ํ–‰ํ•ฉ๋‹ˆ๋‹ค. cartridge.

์šฐ๋ฆฌ ๋ฐœ๋ช…ํ’ˆ์˜ ์ฃผ์š” ์ž„๋ฌด๋Š” ๊ท€ํ•˜์—๊ฒŒ ๊ฐ€์žฅ ์–ด๋ ค์šด ์ž‘์—…์ธ ์ด ์ž‘์—…์„ ์ˆ˜ํ–‰ํ•˜๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค.

Ansible์„ ์‚ฌ์šฉํ•˜๋ฉด ์ž์‹ ๋งŒ์˜ ๋ชจ๋“ˆ์„ ์ž‘์„ฑํ•˜๊ณ  ์ด๋ฅผ ์—ญํ• ์—์„œ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์šฐ๋ฆฌ ์—ญํ• ์€ ์ด๋Ÿฌํ•œ ๋ชจ๋“ˆ์„ ์‚ฌ์šฉํ•˜์—ฌ ํด๋Ÿฌ์Šคํ„ฐ์˜ ๋‹ค์–‘ํ•œ ๊ตฌ์„ฑ ์š”์†Œ๋ฅผ ๊ด€๋ฆฌํ•ฉ๋‹ˆ๋‹ค.

์–ด๋–ป๊ฒŒ ์ž‘๋™ํ•˜๋‚˜์š”? ์„ ์–ธ์  ๊ตฌ์„ฑ์—์„œ ์›ํ•˜๋Š” ํด๋Ÿฌ์Šคํ„ฐ ์ƒํƒœ๋ฅผ ์„ค๋ช…ํ•˜๊ณ  ์—ญํ• ์€ ๊ฐ ๋ชจ๋“ˆ์— ๊ตฌ์„ฑ ์„น์…˜์„ ์ž…๋ ฅ์œผ๋กœ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค. ๋ชจ๋“ˆ์€ ํด๋Ÿฌ์Šคํ„ฐ์˜ ํ˜„์žฌ ์ƒํƒœ๋ฅผ ์ˆ˜์‹ ํ•˜๊ณ  ์ด๋ฅผ ์ž…๋ ฅ๊ณผ ๋น„๊ตํ•ฉ๋‹ˆ๋‹ค. ๋˜ํ•œ ์ธ์Šคํ„ด์Šค ์ค‘ ํ•˜๋‚˜์˜ ์†Œ์ผ“์„ ํ†ตํ•ด ์ฝ”๋“œ๊ฐ€ ์‹คํ–‰๋˜์–ด ํด๋Ÿฌ์Šคํ„ฐ๋ฅผ ์›ํ•˜๋Š” ์ƒํƒœ๋กœ ๋งŒ๋“ญ๋‹ˆ๋‹ค.

๊ฒฐ๊ณผ

์˜ค๋Š˜ ์šฐ๋ฆฌ๋Š” Tarantool Cartridge์— ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์„ ๋ฐฐํฌํ•˜๊ณ  ๊ฐ„๋‹จํ•œ ํ† ํด๋กœ์ง€๋ฅผ ์„ค์ •ํ•˜๋Š” ๋ฐฉ๋ฒ•์„ ์„ค๋ช…ํ•˜๊ณ  ๋ณด์—ฌ์ฃผ์—ˆ์Šต๋‹ˆ๋‹ค. ์ด๋ฅผ ์œ„ํ•ด ์šฐ๋ฆฌ๋Š” ์‚ฌ์šฉํ•˜๊ธฐ ์‰ฝ๊ณ  ๋งŽ์€ ์ธํ”„๋ผ ๋…ธ๋“œ(์šฐ๋ฆฌ์˜ ๊ฒฝ์šฐ ํด๋Ÿฌ์Šคํ„ฐ ์ธ์Šคํ„ด์Šค)๋ฅผ ๋™์‹œ์— ๊ตฌ์„ฑํ•  ์ˆ˜ ์žˆ๋Š” ๊ฐ•๋ ฅํ•œ ๋„๊ตฌ์ธ Ansible์„ ์‚ฌ์šฉํ–ˆ์Šต๋‹ˆ๋‹ค.

์œ„์—์„œ๋Š” Ansible์„ ์‚ฌ์šฉํ•˜์—ฌ ํด๋Ÿฌ์Šคํ„ฐ ๊ตฌ์„ฑ์„ ์„ค๋ช…ํ•˜๋Š” ์—ฌ๋Ÿฌ ๋ฐฉ๋ฒ• ์ค‘ ํ•˜๋‚˜๋ฅผ ๋‹ค๋ฃจ์—ˆ์Šต๋‹ˆ๋‹ค. ๋‹ค์Œ ๋‹จ๊ณ„๋กœ ๋‚˜์•„๊ฐˆ ์ค€๋น„๊ฐ€ ๋˜์—ˆ์Œ์„ ํ™•์ธํ•œ ํ›„์—๋Š” ๋‹ค์Œ ๋‹จ๊ณ„๋ฅผ ๋”ฐ๋ฅด์„ธ์š”. ๋ชจ๋ฒ” ์‚ฌ๋ก€ ํ”Œ๋ ˆ์ด๋ถ ์ž‘์„ฑ์„ ์œ„ํ•ด. ๋‹ค์Œ์„ ์‚ฌ์šฉํ•˜์—ฌ ํ† ํด๋กœ์ง€๋ฅผ ๊ด€๋ฆฌํ•˜๋Š” ๊ฒƒ์ด ๋” ํŽธ๋ฆฌํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. group_vars ะธ host_vars.

๊ณง ํ† ํด๋กœ์ง€์—์„œ ์ธ์Šคํ„ด์Šค๋ฅผ ์˜๊ตฌ์ ์œผ๋กœ ์ œ๊ฑฐ(์ถ”์ถœ)ํ•˜๊ณ , vshard๋ฅผ ๋ถ€ํŠธ์ŠคํŠธ๋žฉํ•˜๊ณ , ์ž๋™ ์žฅ์•  ์กฐ์น˜ ๋ชจ๋“œ๋ฅผ ๊ด€๋ฆฌํ•˜๊ณ , ์ธ์ฆ์„ ๊ตฌ์„ฑํ•˜๊ณ , ํด๋Ÿฌ์Šคํ„ฐ ๊ตฌ์„ฑ์„ ํŒจ์น˜ํ•˜๋Š” ๋ฐฉ๋ฒ•์„ ์•Œ๋ ค๋“œ๋ฆฌ๊ฒ ์Šต๋‹ˆ๋‹ค. ๊ทธ๋™์•ˆ ํ˜ผ์ž ๊ณต๋ถ€ํ•  ์ˆ˜ ์žˆ์–ด์š” ๋ฌธ์„œ ํด๋Ÿฌ์Šคํ„ฐ ๋งค๊ฐœ๋ณ€์ˆ˜๋ฅผ ๋ณ€๊ฒฝํ•˜์—ฌ ์‹คํ—˜ํ•ด ๋ณด์„ธ์š”.

๋ญ”๊ฐ€ ์•ˆ๋˜๋ฉด ๊ผญ ํ•ด๋ณด์„ธ์š” ์•Œ๋ฆฌ๋‹ค ๋ฌธ์ œ์— ๋Œ€ํ•ด ์šฐ๋ฆฌ์—๊ฒŒ. ๋น ๋ฅด๊ฒŒ ๋ถ„ํ•ดํ•ด๋“œ๋ฆฌ๊ฒ ์Šต๋‹ˆ๋‹ค!

์ถœ์ฒ˜ : habr.com

์ฝ”๋ฉ˜ํŠธ๋ฅผ ์ถ”๊ฐ€