Sau bài hướng dẫn cài đặt và cấu hình cơ bản, chúng ta tiếp tục đi tới phần nâng cao để có 1 hệ thống Elasticsearch đáp ứng được performance tốt hơn, bài viết này cóp nhặt với nhiều nguồn khác nhau, hi vọng giúp bạn có thêm những cách tối ưu cho hệ thống đang chạy của bạn.
Elasticsearch sử dụng thư mục mmapfs theo mặc định để lưu trữ các chỉ số của nó. Giới hạn hệ điều hành mặc định về số lượng mmap có thể quá thấp, điều này có thể dẫn đến các lỗi của bộ nhớ. Vì vậy ta có thể tăng số lượng lên bằng câu lệnh sau trên Centos 7.
Mặc định thì hệ điều hành Centos 7 để swappiness bằng 30, tuy nhiên để tối ưu cho Elasticsearch hoàn toàn không sử dụng swap nên chúng ta sẽ tắt nó đi.
sysctl vm.swappiness=0
vm.swappiness = 0
4. Tối ưu config/jvm.options
Chúng ta luôn set giá trị min và max JVM heap size bằng nhau, thường ở mức 1/2 tổng bộ nhớ RAM physical, tối đa không vượt quá 30.5GB
## IMPORTANT: JVM heap size
################################################################
##
## You should always set the min and max JVM heap
## size to the same value. For example, to set
## the heap to 4 GB, set:
##
## -Xms4g
## -Xmx4g
##
## See https://www.elastic.co/guide/en/elasticsearch/reference/current/heap-size.html
## for more information
##
Cấu hình GC, log4j cũng ở trong config này, ( cái này expert quá nên mình chưa thử)
5. Cấu hình Elasticsearch
vi config/elasticsearch.yml
Lock toàn bộ memory khi khởi động
bootstrap.mlockall: true
# Lock the memory on startup:
#
#bootstrap.memory_lock: true
#
# Make sure that the heap size is set to about half the memory available
# on the system and that the owner of the process is allowed to use this
# limit.
#
# Elasticsearch performs poorly when the system is swapping the memory.
#
Trên đây là 1 số cấu hình cần được tối ưu để chạy Elasticsearch, hi vọng có thể giúp bạn lúc bắt đầu, tuy nhiên, có thể 1 số cấu hình không được chính xác và mang tính chủ quan, hi vọng được sự góp ý của các bạn.
Elasticsearch là một phần mềm mã nguồn mở và miễn phí của Elastic, dựa trên Apache Lucene, là platform được sử dụng cho việc phân phối tìm kiếm và phân tích dữ liệu trong thời gian thực, được sử dụng rộng rãi do tính dễ sử dụng, tính năng mạnh mẽ và khả năng mở rộng tốt, bạn có thể sử dụng các phương thức HTTP để giao tiếp qua RESTful để thao tác với dữ liệu, thân thiện với người sử dụng cũng như các nhà phát triển.
Elasticsearch được sử dụng rộng rãi cho các dự án cá nhân cũng như là search engine chính trong các công ty lớn. Tuy có rất nhiều bài viết, tutorial đề cập tới việc hướng dẫn cài đặt cũng như cấu hình, nhưng hi vọng bài viết này sẽ cung cấp cho bạn 1 cách chi tiết và trọn vẹn nhất để thực hiện trên bản Centos 7 và Elasticsearch phiên bản mới nhất 6.2
Các bước cài đặt
1. Cài đặt Java 8
Do Elasticsearch được viết bằng Java nên bạn cần có 1 JRE để chạy nó, ở đây mình sử dụng JDK 8 bản update 171 mới nhất.
java -version
java version “1.8.0_171”
Java(TM) SE Runtime Environment (build 1.8.0_171-b11)
Java HotSpot(TM) 64-Bit Server VM (build 25.171-b11, mixed mode)
2. Download và cài đặt Elasticsearch
Vào trang chủ https://www.elastic.co/downloads và download bản mới nhất hiện tại là 6.2.4
bin lib logs NOTICE.txt README.textile
config LICENSE.txt modules plugins
3. Cấu hình Elasticsearch
Các file cấu hình cần chú ý:
ls config/
elasticsearch.yml jvm.options log4j2.properties
Bạn có thể sửa lại theo ý mình cho các file config này, nếu không cần thiết thì để nguyên và thực hiện sau trong phần tunning cho Elasticsearch.
Khởi chạy Elasticsearch
./bin/elasticsearch
Sample output:
[2018-05-28T02:56:03,739][INFO ][o.e.n.Node ] [] initializing …
[2018-05-28T02:56:03,846][INFO ][o.e.e.NodeEnvironment ] [zqsXYde] using [1] data paths, mounts [[/ (rootfs)]], net usable_space [10.4gb], net total_space [17.4gb], types [rootfs]
[2018-05-28T02:56:03,846][INFO ][o.e.e.NodeEnvironment ] [zqsXYde] heap size [1007.3mb], compressed ordinary object pointers [true]
[2018-05-28T02:56:03,850][INFO ][o.e.n.Node ] node name [zqsXYde] derived from node ID [zqsXYdeEQ8ifax0sYq72gg]; set [node.name] to override
[2018-05-28T02:56:03,850][INFO ][o.e.n.Node ] version[6.2.4], pid[1624], build[ccec39f/2018-04-12T20:37:28.497551Z], OS[Linux/3.10.0-693.5.2.el7.x86_64/amd64], JVM[Oracle Corporation/Java HotSpot(TM) 64-Bit Server VM/1.8.0_171/25.171-b11]
[2018-05-28T02:56:03,851][INFO ][o.e.n.Node ] JVM arguments [-Xms1g, -Xmx1g, -XX:+UseConcMarkSweepGC, -XX:CMSInitiatingOccupancyFraction=75, -XX:+UseCMSInitiatingOccupancyOnly, -XX:+AlwaysPreTouch, -Xss1m, -Djava.awt.headless=true, -Dfile.encoding=UTF-8, -Djna.nosys=true, -XX:-OmitStackTraceInFastThrow, -Dio.netty.noUnsafe=true, -Dio.netty.noKeySetOptimization=true, -Dio.netty.recycler.maxCapacityPerThread=0, -Dlog4j.shutdownHookEnabled=false, -Dlog4j2.disable.jmx=true, -Djava.io.tmpdir=/tmp/elasticsearch.BOVwKawi, -XX:+HeapDumpOnOutOfMemoryError, -XX:+PrintGCDetails, -XX:+PrintGCDateStamps, -XX:+PrintTenuringDistribution, -XX:+PrintGCApplicationStoppedTime, -Xloggc:logs/gc.log, -XX:+UseGCLogFileRotation, -XX:NumberOfGCLogFiles=32, -XX:GCLogFileSize=64m, -Des.path.home=/data/elastic/elasticsearch, -Des.path.conf=/data/elastic/elasticsearch/config]
….
[2018-05-28T02:56:09,185][INFO ][o.e.t.TransportService ] [zqsXYde] publish_address {127.0.0.1:9300}, bound_addresses {[::1]:9300}, {127.0.0.1:9300} [2018-05-28T02:56:09,200][WARN ][o.e.b.BootstrapChecks ] [zqsXYde] max file descriptors [4096] for elasticsearch process is too low, increase to at least [65536] [2018-05-28T02:56:09,201][WARN ][o.e.b.BootstrapChecks ] [zqsXYde] max virtual memory areas vm.max_map_count [65530] is too low, increase to at least [262144]
[2018-05-28T02:56:12,290][INFO ][o.e.c.s.MasterService ] [zqsXYde] zen-disco-elected-as-master ([0] nodes joined), reason: new_master {zqsXYde}{zqsXYdeEQ8ifax0sYq72gg}{3MVumgkjQGK04HXp82FPCA}{127.0.0.1}{127.0.0.1:9300}
[2018-05-28T02:56:12,311][INFO ][o.e.c.s.ClusterApplierService] [zqsXYde] new_master {zqsXYde}{zqsXYdeEQ8ifax0sYq72gg}{3MVumgkjQGK04HXp82FPCA}{127.0.0.1}{127.0.0.1:9300}, reason: apply cluster state (from master [master {zqsXYde}{zqsXYdeEQ8ifax0sYq72gg}{3MVumgkjQGK04HXp82FPCA}{127.0.0.1}{127.0.0.1:9300} committed version [1] source [zen-disco-elected-as-master ([0] nodes joined)]])
[2018-05-28T02:56:12,361][INFO ][o.e.g.GatewayService ] [zqsXYde] recovered [0] indices into cluster_state
[2018-05-28T02:56:12,368][INFO ][o.e.h.n.Netty4HttpServerTransport] [zqsXYde] publish_address {127.0.0.1:9200}, bound_addresses {[::1]:9200}, {127.0.0.1:9200}
[2018-05-28T02:56:12,368][INFO ][o.e.n.Node ] [zqsXYde] started
Trong output trên có warning những thứ cần phải tunning cho phù hợp, mình sẽ đề cập ở bài viết sau.
(Not all processes could be identified, non-owned process info
will not be shown, you would have to be root to see it all.)
tcp6 0 0 127.0.0.1:9200 :::* LISTEN 1624/java off (0.00/0/0)
tcp6 0 0 ::1:9200 :::* LISTEN 1624/java off (0.00/0/0)
tcp6 0 0 127.0.0.1:9300 :::* LISTEN 1624/java off (0.00/0/0)
tcp6 0 0 ::1:9300 :::* LISTEN 1624/java off (0.00/0/0)
Như vậy là chúng ta đã xong phần cơ bản với cài đặt và cấu hình Elasticsearch, rất đơn giản và dễ hiểu phải không nào? Phần tiếp theo mình sẽ viết thêm về tunning và cấu hình nâng cao, cũng như một số thành phần có liên quan để xây dựng 1 hệ sản phẩm Elastic.
VMWare Player là 1 phần mềm ảo hóa được sử dụng rộng rãi trong cộng đồng system admin, phục vụ cho việc làm lab cũng như thử nghiệm những hệ điều hành mới mà không cần phải cài đặt trên máy host và đây là phần mềm ưa thích của mình thay vì cài VirtualBox hay VMWare Workstation.
Thông tin về hệ thống, VMWare Player 14.0.0 trên OS kernel 4.13.0-37-gerenic
Tuy nhiên, sau khi cài đặt bản VmWare Workstation 14 Player trên Ubuntu 16.04 thì mình gặp phải lỗi sau khi tạo 1 VM.
Mặc dù RAM của host còn available rất nhiều 😕
Sau khi search google thì mình được biết đây là bug của VMWare trên host kernel 4.13 và mình đã follow thực hiện hotfix theo các bước sau.
Thông tin hotfix ở đây https://github.com/mkubecek/vmware-host-modules/commit/770c7ffe611520ac96490d235399554c64e87d9f
Nginx đã bắt đầu hỗ trợ gRPC từ bản 1.13.10, tuy nhiên vẫn trang trên mainline, chưa stable, thông tin được cập nhật từ trang chủ https://www.nginx.com/blog/nginx-1-13-10-grpc/
Sau đây, mình sẽ hướng dẫn các bạn complie nginx từ source theo document https://docs.nginx.com/nginx/admin-guide/installing-nginx/installing-nginx-open-source/ trên Centos 7.
Fact:
cat /etc/redhat-release
CentOS Linux release 7.3.1611 (Core)
Cài các gói phụ thuộc cần thiết bao gồm, openssl, zlib, pcre
$ wget ftp://ftp.csx.cam.ac.uk/pub/software/programming/pcre/pcre-8.41.tar.gz
$ tar -zxf pcre-8.41.tar.gz
$ cd pcre-8.41
$ ./configure
$ make
$ make install
$ wget http://zlib.net/zlib-1.2.11.tar.gz
$ tar -zxf zlib-1.2.11.tar.gz
$ cd zlib-1.2.11
$ ./configure
$ make
$ make install
$ wget http://www.openssl.org/source/openssl-1.0.2k.tar.gz
$ tar -zxf openssl-1.0.2k.tar.gz
$ cd openssl-1.0.2k
$ ./config–prefix=/usr
$ make
$ make install
Download source
$ wget http://nginx.org/download/nginx-1.13.10.tar.gz
$ tar zxf nginx-1.13.10.tar.gz
$ cd nginx-1.13.10
Docker là một hệ thống mã nguồn mở, hỗ trợ đóng gói và tự động triển khai phần mềm trong các container. Nó cung cấp một cách nhanh, gọn để tạo môi trường hoạt động cho phần mềm, giảm thiểu rủi ro giữa dev và ops khi developper phát triển trên cùng một môi trường như môi trường vận hành, giúp dễ dàng tự động hóa và tăng tốc chu trình phát triển phần mềm (dev, test, deploy…).
Ưu điểm:
Triển khai ứng dụng nhanh chóng : container bao gồm các yêu cầu tối thiểu để chạy của ứng dụng , làm giảm kích thước của chúng và cho phép chúng được triển khai nhanh chóng .
Khả năng di chuyển linh động : một ứng dụng và tất cả các phụ thuộc của nó có thể được gói vào một container duy nhất , độc lập với các phiên bản máy chủ của Linux kernel , phân phối nền tảng , hoặc mô hình triển khai.Container này có thể được chuyển sang một máy chạy Docker, và được thực hiện mà không hề có vấn đề tương thích hay không.
Kiểm soát phiên bản và tái sử dụng.
Dễ dàng chia sẻ : với Docker Hub hoặc 1 public Registry việc chia sẻ container rất dễ dàng thực hiện và thân thiện với mọi người kể cả developer, tester, admin system.
Nhẹ và chi phí tối thiểu : Docker image thường rất nhỏ , tạo điều kiện cho việc kiểm thử và giảm thời gian để triển khai các ứng dụng mới container.
I.2 Khi nào sử dụng docker
Tách biệt các cài đặt cho từng ứng dụng, không gây ảnh hưởng lẫn nhau.
Xây dựng môi trường làm việc mà không quá tốn nhiều thời gian cho việc cài đặt.
Đồng nhất môi trường phát triển.
Đóng gói môi trường thực thi một cách nhỏ gọn kèm theo cho dự án.
I.3 Kiến trúc của Docker
Docker sử dụng kiến trúc client-server:
Client: Là bộ công cụ ở dạng dòng lệnh dùng để pull/push/search các templates dựng sẵn từ registry công cộng hoặc riêng một tổ chức nào đó thông qua Restful API và tập hợp các lệnh khác để tương tác với container.
Server: chạy trên nền hệ điều hành của máy chủ dưới dạng một daemon, chịu trách nhiệm cho các tác vụ như đóng gói, thực thi, tải về container image.
I.4 Các thành phần của docker
Docker được tạo bởi 3 phần chính : Container, Image, Registry
Container: dùng để tách biệt ứng dụng và các thành phần thưc thi của ứng dụng đó với các container khác trên cùng 1 máy chủ và với chính máy chủ chứa container đó.
Image: là các template dựng sẵn đã chứa đủ các thành phần của môi trường thực thi cần cho ứng dụng và được dùng để tạo các container. Chẳng hạn một image chứa hệ điều hành Ubuntu đã cài đặt sẵn Apache và ứng dụng web
Registry : Là kho chứa images. Người dùng có thể tạo ra các images của mình và tải lên đây hoặc tải về các images được chia sẻ (Docker Hub)
Hình 1.1 Mô hình tương tác giữa các thành phần docker
Docker Daemon
Như thế hiện trên hình vẽ , Docker daemon chạy trên các máy host. Người dùng sẽ không tương tác trực tiếp với các daemon, mà thông qua Docker Client.
Docker Client
Là giao diện người dùng của Docker, nó cung cấp cho người dùng giao diện dòng lệnh và thực hiện phản hồi với các Docker daemon.
Docker images
Là một template chỉ cho phép đọc, ví dụ một image có thể chứa hệ điều hành Ubuntu và web app. Images được dùng để tạo Docker container. Docker cho phép chúng ta build và cập nhật các image có sẵn một cách cơ bản nhất, hoặc bạn có thể download Docker images của người khác.
Docker Container
Docker container có nét giống với các directory. Một Docker container giữ mọi thứ chúng ta cần để chạy một app. Mỗi container được tạo từ Docker image. Docker container có thể có các trạng thái run, started, stopped, moved và deleted.
I.5 Sự khác nhau giữa Docker và Máy Ảo
Hình 1.2 Mô hình docker và máy ảo
Cùng xét mô hình kiến trúc của VM: Mỗi ứng dụng được ảo hóa bao gồm chính ứng dụng đấy và cũng chứa các phụ thuộc của nó giống như bên container. Tuy nhiên bên VM sẽ kèm theo thêm 1 guest OS. Điều này dẫn tới việc đóng gói ứng dụng được ảo hóa sẽ có dung lượng lên tới hàng GB.
Khác với container là chia sẻ host OS đồng nghĩa với việc các container sẽ có OS giống nhau thì với máy ảo, mỗi một VM có thể có OS khác so với các VM khác và thậm trí OS của các VM hoàn toàn có thể khác với host OS.
Xét về tính linh hoạt: Nếu như bạn muốn bảo trì máy host, với container thì khi bảo trì mà buộc phải khởi động lại máy thì đồng nghĩa với việc hoạt động của các container có trong máy đó sẽ bị gián đoạn. Tuy nhiên với VM, bạn hoàn toàn có thể di chuyển các VM có trong máy cần được bảo dưỡng sang tạm các máy tính khác. Điều này giúp ứng dụng có trong các VM hoạt động mà không bị gián đoạn.
Xét về tính an toàn: Với container, do dùng chung OS nên nếu có lỗ hổng nào đấy ở kernel của host OS thì nó sẽ ảnh hưởng tới toàn bộ container có trong host OS đấy
Sử dụng Docker tạo và xóa container nhanh, dễ dàng, trong khi Virtual Machine yêu cầu cài đặt đầy đủ và sử dụng nhiều tài nguyên của máy để thực thi việc cài đặt đó
Container ưu điểm là lightweight, có thể chạy nhiều container hơn VM khi triển khai trên cùng một máy chủ. Container bật tắt nhẹ nhành, nhanh chóng
VM có thể migrate giữa các máy chủ trong lúc chạy. Container thì phải dừng hẳn thì mới migrate được.
Hypervisor có thời gian khởi động trung bình là 20s, thay đổi phụ thuộc vào tốc độ của ổ đĩa.
Containers khởi động và làm cho ứng dụng sẵn sàng chạy trong 500ms, mang lại tính khả thi cao cho những dự án cần sự mở rộng nhanh.
I.6 Quy trình thực thi của một hệ thống sử dụng Docker.
Như hình vẽ trên , một hệ thống Docker được thực thi với 3 bước chính :
Build -> Push -> Pull,Run
a, Build.
Đầu tiên chúng ta sẽ tạo một dockerfile, trong dockerfile này chính là code của chúng ta.
Dockerfile này sẽ được Build tại một máy tính đã cài đặt Docker Engine.
Sau khi build ta sẽ thu được Container, trong Container này chứa bộ thư viện và ứng dụng của chúng ta.
b, Push.
Sau khi có được Container, chúng ta thực hiện push Container này lên đám mây và lưu trữ ở đó.Việc push này có thể thực hiện qua môi trường mạng Internet.
c, Pull, Run
Giả sử một máy tính muốn sử dụng Container chúng ta đã push lên đám mây (máy đã cài Docker Engine) thì bắt buộc máy phải thực hiện việc Pull container này về máy. Sau đó thực hiện Run Container này.
II.Cấu trúc của một Docker File
II.1 Docker File
Dockerfile là 1 file text chứa các lệnh thực thi để build 1 image cho docker. Với dockerfile chúng ta có 1 phương tiện để build các image 1 cách tự động và share với nhau 1 cách dễ dàng, 1 team của 1 dự án có thể dung dockerfile để tạo các môi trường dev và test đồng nhất với nhau
II.2 Cấu trúc tập lệnh của một Docker File
+ FROM <image>
Đây là lệnh phải có với bất kỳ 1 dockerfile nào, và phải nằm ở line đầu tiên của file
Mục đích của lệnh là set image làm cơ sở để từ đó tạo nên image muốn build
Ví dụ: FROM ubuntu:12.04
=>Nếu image cơ sở này không tồn tại trong local thì docker sẽ tự pull image này từ Docker Hub
+ MAINTAINER <name>
Lệnh dùng để set tác giả của image, có thể có hoặc không
+ RUN <command>
Lệnh dùng để thực thi 1 command trên hệ thống(của image)
+ CMD <command>
Trong 1 dockerfile chỉ có thể có 1 lệnh CMD. Lệnh này để tạo command được thưc thi khi khởi chạy image
+ ADD <src> <dest>
Lệnh dùng để copy file từ remote hoặc local file được chỉ định ở <src> vào path trên container được chỉ đinh ở <dest>
+ EXPOSE <port> [<port>]
Lệnh dùng để chỉ định rằng containner của image sẽ listen trên các port nào đó trong khi chạy
III. Một số tập lệnh làm việc với Docker ( Docker Engine)
+Pull một image từ Docker Hub $ docker pull {image_name}
+Liệt kê các images hiện có $ docker images
+Xóa một image $ docker rmi {image_id/name}
+Liệt kê các container đang chạy $ docker ps $ docker ps -a #Liệt kê các container đã tắt
+Xóa một container $ docker rm -f {container_id/name}
+Đổi tên một container $ docker rename {old_container_name} {new_container_name}
+Khởi động một container $ docker start {new_container_name} $ docker exec -it {new_container_name} /bin/bash
+Tạo mới một container, đồng thời khởi động với tùy chọn cổng và volume $ docker run –name {container_name} -p {host_port}:{container_port} -v {/host_path}:{/container_path} -it {image_name} /bin/bash
+Xem các thay đổi trên container $ docker diff {container_name}
+Commit các thay đổi trên container và image $ docker commit -m “message” {container_name} {image_name}
+Save image thành file .tar $ docker save {image_name} > {/host_path/new_image.tar}
+Tạo một image mới từ file .tar $ cat musashi.tar | docker import – {new_image_name}:latest
+Xem lịch sử các commit trên image $ docker history {image_name}
+Khôi phục lại images từ IMAGE_ID $ docker tag {iamge_id} {image_new_name}:{tag}
+Build một image từ container $ docker build -t {container_name} . Dấu . ở đây có thể hiểu là Dockerfile đang nằm trong thư mục hiện tại.
Tham khảo phần demo tạo 1 Docker file & container qua link github sau:
https://github.com/lieunn/docker-lamp
IV. Docker Storage
Volume trong Docker
=>Volume trong Docker được dùng để chia sẻ dữ liệu cho container. Để sử dụng volume trong docker dùng cờ hiệu (flag) -v trong lệnh docker run.
Có thể sử dụng Volume trong Docker trong những trường hợp sau
Chia sẻ giữa container và container.
Chia sẻ giữa container và host.
Sử dụng volume để gắn (mount) một thư mục nào đó trong host với container.
Sử dụng volume để chia sẻ dữ liệu giữa host và container
Trong tình huống này thư mục trên máy host (máy chứa container) sẽ được mount với một thư mục trên container, dữ liệu sinh ra trên thư mục được mount của container sẽ xuất hiện trên thư mục của host.
* Có 2 chế độ chia sẻ volume trong docker, đó là read-write (rw) hoặc read-only (ro). Nếu không chỉ ra cụ thể thì mặc định sử dụng chế độ read-write. Ví dụ chế độ read-only, sử dụng tùy chọn ro.
$ docker run -it -v $(pwd)/bindthis:/var/www/html/webapp:ro ubuntu bash
Các lưu ý về volume trong Docker
Đường dẫn trong cờ hiệu -v phải là đường dẫn tuyệt đối, thường dùng $(pwd)/ten_duong_dan để chỉ đúng đường dẫn.
Có thể chỉ định việc mount giữa thư mục trên host và thư mục trên container ở các chế độ read-wirte hoặc read-only, mặc định là read-write.
Để chia sẻ volume dùng tùy chọn –volumes-from
Sử dụng Docker với một số storage khác
=>Nhu cầu về lưu trữ data ngày càng tăng => cần 1 giải pháp storage hợp lý, có thể kể đến Ceph, Glusterfs, Openfiler ….
=> Có thể xây dựng một hệ thống storage ceph, gluster tách riêng sau đó sẽ mount các volume share tương ứng về volume local trên docker container
Hình 3.1.Mô hình lưu trữ Ceph-Docker
Như hình trên thì ta sẽ xây dựng một hệ thống ceph cluster chứa các volume cần share, client sẽ xây dựng 2 host docker để map volume share về local và mount vào các docker container
Network của docker được quản lý thông qua một virtual bridge gọi là docker0. Mục đích của việc này là để tạo ra một network độc lập, tách biệt với môi trường khác.
Khi chúng ta khởi động docker deamon (thông qua sudo service docker startchẳng hạn) thì những step dưới đây sẽ diễn ra:
+ Virtual bridge docker0 sẽ được tạo ra=>Docker tự dộng tìm ra một khoảng ip range còn trống từ trong route của máy host=>Chọn ra random một khoảng ip bất kì=>Assign khoảng ip đó cho docker0
Sau đó khi chúng ta khởi động một container bất kì, thì container đó sẽ được assign những thứ dưới đây:
+ veth (Virtual Eithernet) interface gắn với docker0
+ một ip bất kì trong range mà docker0 vừa thu được ở trên
Networking giữa các container với nhau
Để kiểm soát việc các container có làm việc được với nhau hay không, chúng ta thông qua parameter -icc của docker daemon.
+ Khi -icc = true thì container có thể nói chuyện được với nhau.
+ Khi -icc = false thì các container sẽ bị tách biệt với nhau
Ngoài ra để public một port nào đó ra ngoài chúng ta cũng phải chỉ định EXPOSE <port> trong Dockerfile hoặc là –expose <port> khi khởi động container.
Cụ thể hơn, để các container nói chuyện được với nhau, docker0 sử dụng một tính năng gọi là –link. Khi khởi động một container nào đó chúng ta phải chỉ định –link containerName:containerAlias , nhờ đó mà service trong container đó sẽ tìm thấy service muốn kết nối đến thông qua biến môi trường.
Kết nối từ network ở ngoài vào container
Để kết nối từ network ở ngoài vào container thì chúng ta phải mapping port của máy host với port mà container expose thông qua docker0.
Ví dụ chúng ta muốn map port 8080 của máy host vào port 80 của docker , sử dụng apache container:
$ ID=$(docker run -d -p 8080:80 tcnksm/apache)
caad0cfc2a0
Chúng ta có thể kiểm tra mapping như sau
$ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
caad0cfc2a03 tcnksm/apache:latest /usr/sbin/apache2 -D About a minute ago Up About a minute 0.0.0.0:8080->80/tcp elegant_thompson
=>Mặc định, docker dùng bridge network. Khi cài đặt docker, bạn sẽ thấy một interface docker0 trên host. Khi khởi chạy một container trong host, một interface mới đại diện cho nó sẽ được sinh ra trên host:
4: docker0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP
Compose là công cụ giúp định nghĩa và khởi chạy multi-container Docker applications. Trong Compose, chúng ta sử dụng Compose file để cấu hình application’s services. Chỉ với một câu lệnh, lập trình viên có thể dễ dàng create và start toàn bộ các services phục vụ cho việc chạy ứng dụng.
Compose là một công cụ tuyệt vời không chỉ dùng cho development, testing, staging environments, mà còn ứng dụng trong CI workflows. Việc sử dụng Docker Compose được tóm lược trong 3 bước cơ bản sau:
Khai báo app’s environment với Dockerfile.
Khai báo các services cần thiết để chạy app trong docker-compose.yml.
Run docker-compose up và Compose sẽ start và run app.
Setup Docker-Compose tham khảo qua link github sau:
https://github.com/lieunn/docker-compose
VII. Docker-Swarm
Docker swarm là một công cụ giúp chúng ta tạo ra một clustering Docker. Nó giúp chúng ta gom nhiều Docker Engine lại với nhau và ta có thể “nhìn” nó như duy nhất một virtual Docker Engine.
Trong phiên bản v1.12.0, Docker Swarm là một tính năng được tích hợp sẵn trong Docker Engine.
Trong phần này, tôi sẽ tạo ra 1 cụm cluster gồm 1 manager và 2 worker chạy dịch vụ web-server.
node manager sẽ là node quản lý cluster.
node worker là các node chạy dịch vụ. Nếu mà node worker die thì node manager sẽ run container trên chính nó.
Hazelcast là một mạng lưu trữ dữ liệu trên bộ nhớ Ram (in-memory data grid). Hazelcast đưa ra cài đặt của các interface trong Java như: Map, Queue, Excecutor Service, Lock… Nó được thiết kế rất nhẹ và dễ sử dụng.
Hazelcast được cài đặt bằng ngôn ngữ Java, client hỗ trợ các ngôn ngữ Java, C/C++, C# , Python…
Hazelcast cũng có thể được xem như một giao thức lưu đệm (memcache protocol).
Hazelcast sử dụng cơ chế mạng ngang hàng, không có master và slave. Tất cả các node lưu số lượng dữ liệu như nhau, và xử lý bằng nhau.
Hazelcast lưu trữ mọi thứ trên Ram (in-memory). Nó được thiết kế để thực thi rất nhanh các thao tác đọc và cập nhật (read/update) dữ liệu.
Hazelcast lưu các bản sao (backup) của mỗi mảnh dữ liệu trên các node khác nhau. Khi một node bị lỗi, dự liệu trên node đó sẽ được khôi phục lại từ bản sao (bản backup) và cụm Hazelcast vẫn hoạt động bình thường, không có thời gian ngừng hoạt động (downtime = 0).
Sharding(các mảnh dữ liệu) trong Hazelcast được gọi là các Partition. Mặc định Hazelcast có 271 partition. Các partition được phân tán trên tất cả các node của cụm. Hazelcast cũng tạo bản backup của các partition và phân tán chúng trên các node.
2> Một số Use Case Hazelcast.
Application scaling
Cache-as-a-service
Cross-JVM communication and shared storage
Distributed cache, often in front of a database
In-memory processing and Analytics
In-memory computing
Internet of Things infrastructure
Key-value database
Memcached alternative with a protocol compatible interface[4]
Microservices infrastructure
NoSQL data store
Spring Cache
Web Session clustering
3> Kiến trúc Client-Server Hazelcast.
Hazelcast cung cấp một kiến trúc phân mảnh & phân tán dữ liệu qua cluster node.
+ Hazelcast IMDG có những đặc điểm sau:
Dữ liệu được lưu trữ trên RAM.
Nhiều bản sao được lưu trữ trên nhiều node để auto-recovery dữ liệu trong trường hợp một hoặc nhiều node fail.
Mô hình dữ liệu hướng đối tượng và là kiểu dữ liệu không quan hệ(non-relational).
Resource có thể được tự động thêm hoặc gỡ bỏ để tăng lượng CPU và RAM.
Dữ liệu có thể được duy trí từ một hazelcast node đến một cơ sở dữ liệu quan hệ hoặc NoSQL.
Một Java API Map có thể truy xuất vào kho dữ liệu phân tán key-value.
– update management-center data
– update multicast data
– update tcp-ip data
<group>
<name>sandbox</name>
<password>[email protected]#1234</password>
</group>
<management-center enabled=”true”>http://192.168.175.130:8080/mancenter</management-center>
<network>
<port auto-increment=”true” port-count=”100″>5701</port>
<outbound-ports>
<!–
Allowed port range when connecting to other nodes.
0 or * means use system provided port.
–>
<ports>0</ports>
</outbound-ports>
<join>
<multicast enabled=”false”>
<multicast-group>224.2.2.3</multicast-group>
<multicast-port>54327</multicast-port>
</multicast>
<tcp-ip enabled=”true”>
<interface>192.168.175.128</interface>
<member-list>
<member>192.168.175.128</member>
<member>192.168.175.129</member>
</member-list>
</tcp-ip>
<aws enabled=”false”>
$ cd /build/hazelcast-3.9/bin
$ chmod +x *.sh
$ ./start.sh => check port default 5701 is listen and join cluster (member list)
– update management-center data
– update multicast data
– update tcp-ip data
<group>
<name>sandbox</name>
<password>[email protected]#1234</password>
</group>
<management-center enabled=”true”>http://192.168.175.130:8080/mancenter</management-center>
<network>
<port auto-increment=”true” port-count=”100″>5701</port>
<outbound-ports>
<!–
Allowed port range when connecting to other nodes.
0 or * means use system provided port.
–>
<ports>0</ports>
</outbound-ports>
<join>
<multicast enabled=”false”>
<multicast-group>224.2.2.3</multicast-group>
<multicast-port>54327</multicast-port>
</multicast>
<tcp-ip enabled=”true”>
<interface>192.168.175.129</interface>
<member-list>
<member>192.168.175.128</member>
<member>192.168.175.129</member>
</member-list>
</tcp-ip>
<aws enabled=”false”>
$ cd /build/hazelcast-3.9/bin
$ chmod +x *.sh
$ ./start.sh => check port default 5701 is listen and join cluster (member list)
Là dân system chắc là các bạn cũng đã từng nghe nhắc nhiều đến cụm từ “Configuration Management” hoăc cứ google là ra hàng tá bài viết liên quan.
Vâng! Configuration Management (CM) có thể hiểu là công cụ hỗ trợ, cấu hình, cài đặt hệ thống một cách tự động. Có rất nhiều công cụ như Ansible, Chef, Puppet, Saltstack … Loạt bài viết này sẽ không tập trung vào việc so sánh các công cụ CM mà chỉ hướng dẫn bạn cách cài đặt và sử dụng Ansible.
1. Ansible là cái gì?
Ansible có thể hiểu nôm na là công cụ dùng để quản lý cài đặt, cấu hình hệ thống một cách tập trung và cho phép thực thi câu lệnh điều khiển.
2. Ansible có những tính năng gì hay ho ?
+ Dự phòng tài nguyên (provisioning)
+ Quản lý cấu hình (configuration management)
+ Triển khai ứng dụng (app deployment)
+ Giao hàng liên tục (continous delivery)
+ Bảo mật và tuân thủ (security and compliance)
+ Điều phối (orchestration).
3. Đặc điểm của Ansible
+ Không cần cài đặt phần mềm lên các agent, chỉ cần cài đặt tại master.
+ Không service, daemon, chỉ thực thi khi được gọi
+ Cú pháp dễ đọc, dễ học, dễ hiểu
4. Ansible playbook thì sao?
Ansible playbook giúp chúng ta tổ chức công việc của mình theo nhiều cách. Trong hình thức trực tiếp nhất, chúng ta có thể làm việc với các module của Ansible sử dụng công cụ dòng lệnh “ansible” và file inventory.
4.1. Inventory
File inventory giúp Ansible biết các server mà nó cần kết nối sử dụng SSH, thông tin kết nối nó yêu cầu, và tùy chọn các biến gắn liền với các server này. File inventory có định dạng là INI. Trong file inventory, chúng ta có thể chỉ định nhiều hơn một máy chủ và gom chúng thành nhiều nhóm.
Ex: file inventory hosts.ini như sau
[webservers]
192.168.175.129
192.168.175.130
4.2 Task (nhiệm vụ)
Một khái niệm quan trọng khác là các task. Mỗi task của Ansible chứa một tên, một module để gọi, các tham số của module, và tùy chọn các điều kiện trước và sau. Chúng cho phép chúng ta gọi các module Ansible và truyền thông tin tới các task kế tiếp.
4.3 Vars (Các biến)
Biến hữu dụng cho việc tái sử dụng thông tin chúng ta cung cấp hoặc tập hợp. Chúng ta có thể định nghĩa biến trong các file inventory, các file YAML hoặc trong các playbook.
4.4 Playbook
Ansible playbook được viết bằng cú pháp YAML. Nó có thể chứa nhiều hơn một play. Mỗi play chứa tên của các nhóm máy chủ để kết nối tới và các nhiệm vụ nó cần thực hiện. Nó cũng có thể chứa các biến/các role/các handler, nếu đã định nghĩa.
Ex: cấu trúc của một playbook
– hosts: dbservers
gather_facts: no
vars:
who: World
tasks:
– name: say hello
debug: msg=”Hello {{ who }}”
– name: retrieve the uptime
command: uptime
Trong playbook trên, chúng ta đã nói rằng Ansible sẽ thao tác trên các server đã được định nghĩa trong nhóm máy chủ “dbservers”. Chúng ta đã tạo một biến gọi là “who” và sau đó chúng ta định nghĩa các nhiệm vụ của chúng ta. Chú ý rằng trong nhiệm vụ đầu tiên nơi chúng ta in ra một thông điệp debug, chúng ta đã sử dụng biến “who” và Ansible in “Hello World” ra màn hình. Trong nhiệm vụ thứ 2, chúng ta nói với Ansible kết nối tới mỗi máy chủ và sau đó thực thi lệnh “uptime”.
5. Hướng dẫn cài đặt và tổ chức một ansible playbook
5.1 Cài đặt.
Việc cài đặt ansible khá là đơn giản:
Trên CentOS:
$ yum install epel-release
$ yum install ansible Trên Ubuntu:
Cấu hình PPA, cài đặt:
$ sudo apt-get install software-properties-common
$ sudo apt-add-repository ppa:ansible/ansible
$ sudo apt-get update
$ sudo apt-get install ansible
Trên các phiên bản Ubuntu cũ, gói software-properties-common có tên khác là python-software-properties
5.2 Viết một playbook cho việc triển khai các dịch vụ
Ở đây mình đã có viết một playbook cho việc deploy các dịch vụ như nginx, mongodb, redis, postgresql.
Mô hình deploy:
+ node master ( 192.168.75.128): cài đặt ansible tool
+ node deploy services (192.168.75.129 & 192.168.75.130): các dịch vụ như nginx, mongodb, redis, postgresql sẽ được deploy trên 2 node này
Các bạn có thể tham khảo playbook qua link github sau:
Tiếp tục câu chuyện ở part 1, trong bài viết này sẽ trình bày các thành phần tiếp theo của hệ thống Stack Overflow theo kiến trúc được cập nhật đến năm 2016.
Cache & Pub/Sub (Redis)
SO sử dụng Redis cho 2 việc là caching và pub/sub cho hệ thống, mặc dù chịu tải khoảng 160 tỷ câu lệnh trong vòng 1 tháng, những mỗi instance chỉ chạy khoảng 2% CPU, ở mức rất thấp. (Chắc chỉ tốn RAM).
SO sử dụng Redis làm caching 2 lớp L1/L2, L1 sử dụng cho HTTP Cache cho web server và bất kỳ ứng dụng nào đang chay, còn L2 dùng để lấy giá trị từ Redis, có thể hiểu là L1 dùng để write, còn L2 dùng để read. Giá trị của key trong Redis theo định dạng protobuf thông qua thư viện protobuf-dot-net của Marc Gravell. Thư viện sử dụng cho client là StackExchange.Redis là một opensource và tự phát triển. Khi mà web server bị miss ở cả 2 L1 và L2, chúng sẽ lấy dữ liệu từ database thông qua query hoặc gọi API…và ghi kết quả vào cache local và Redis, khi đó 1 web server khác muốn lấy giá trị nào đó, có thể miss ở L1 nhưng chắc chắn sẽ lấy được ở L2 hoặc database hoặc thông qua việc gọi API.
Các trang Q&A đều có caching theo dạng key prefix thì đặt ở L1 còn L2 thì chứa database ID.
Bên cạnh 2 server Redis chạy master/slave cho toàn bộ các site hiện có, thì SO còn có thêm 1 server slave machine learning sử dụng cho việc thể hiện các câu hỏi khuyến nghị, job matching …được gọi là Providence.
Server Redis chính thì có 256GB RAM (96GB đã sử dụng) và Providence thì có 384GB RAM (125GB đã sử dụng).
Và tất nhiên không chỉ dùng để caching, SO còn dùng Redis theo cơ chế pub/sub để public 1 message cho toàn bộ subcriber bao gồm đã downstream ở Redis slave, SO dùng cơ chế này để xóa 1 lưu trữ trên L1 của 1 web server khi 1 web server khác bị loại bỏ khỏi tính đồng bộ của hệ thống.
Redis isn’t just for cache though, it also has a publish & subscriber mechanism where one server can publish a message and all other subscribers receive it—including downstream clients on Redis slaves. We use this mechanism to clear L1 caches on other servers when one web server does a removal for consistency, but there’s another great use: websockets.
(Đoạn này hơi rắc rối, mình xin phép để nguyên văn)
NetGain WebSockets
SO sử dụng websocket để push real-time cập nhật của user ví dụ như các thông báo trên top bar, số lượng vote, hay câu hỏi hay câu trả lời mới và 1 vài thứ khác.
Và các server socket này sử dụng raw socket và chạy trên các web tier sử dụng thư viện StackExchange.NetGain, trong peak time( giờ cao điểm) ,số lượng kết nối đồng thời lên tới 500.000, và có những kết nối kéo dài 18 tháng, tác giả không chắc là người đó có tắt browser của mình hay có còn sống không nữa?
Search (Elasticsearch)
Nói chung là không có điều gì thú vị ở đây cả, SO sử dụng Elasticsearch 1.4 và thư viện StackExchange.Elastic cho client và sử dụng cho đường /search trên website, tính toán các câu hỏi có liên quan, và đề xuất khi đặt câu hỏi.
Mỗi cụm cluster ES đều có 3 node trên từng datacenter , và mỗi site đều đánh 1 index. Như site Careers thì có nhiều index hơn và được cấu hình theo 1 cách khác không theo dạng chuẩn, với 3 cụm cluster lớn hơn với SSD và 192 GB RAM và 2x10GBps cho card mạng.
Lý do chính để sử dụng ES là cho việc tìm kiếm full-text SQL một cách dễ dàng và ít chi phí hơn so với việc sử dụng database SQL. Vậy tại sao lại không dùng Solr thay thế cho ES? Việc này có thể xảy ra trong tương lai với version 2.x.
Databases (SQL Server)
SO sử dụng SQL Server là Single_source_of_truth , mọi dữ liệu trên Redis hay ES đều đến từ database và có 2 cụm cluster SQL Server được cài đặt, với mỗi cluster đều có 1 master và 1 replica ở New York, thêm vào đó là 1 replica ở Colorado, và tất cả các bản sao đều chạy bất đồng bộ.
Cụm đầu tiên bao gồm server Dell R720xd, mỗi con có 384GB Ram, 4TB PCIe SSD và 2×12 cores, chúng chứa Stack Overflow, Sites, PRIZM, và dữ liệu Mobile.
Cụm thứ 2 bao gồm server Dell R730xd, mỗi con có 768GB RAM, 6TB PCIe SSD và 2×8 core, chạy những thứ còn lại, bao gồm Talent, OpenID, Chat, Exception log và toàn bộ các trang Q&A ví dụ Super User, Server Fault
Mức sử dụng CPU hiện tại còn khá cao mặc dù đã được optimize, có thể thấy trong biểu đồ sau, với 04 là master, 01 và 03 là replica.
Thư viện
Dưới đây là toàn bộ các thư viện tự phát triển hoặc opensource được sử dụng cho SO.
Dapper (.Net Core) – High-performance Micro-ORM for ADO.Net
Sau một bài viết khá dài và chi tiết của tác giả Nick Craver, chúng ta có thể thấy được toàn bộ những gì phía sau của 1 hệ thống website vô cùng đồ sộ và đáp ứng được hàng triệu người dùng trên toàn thế giới. Bài viết của mình xin dừng ở đây và hi vọng sẽ trở lại với việc tìm hiểu những hệ thống lớn khác.
Không cần phải giới thiệu nhiều về Stack Overflow (SO), bởi vì nó quá nổi tiếng và phổ biến trong cộng đồng developer và có nguyên cụm từ “The full stackoverflow developer” để mô tả những developer sống không thể thiếu website này 😀 System Engineer cũng không ngoại lệ đâu nhé!
Vậy bạn có bao giờ tự hỏi Đằng sau SO là 1 hệ thống được xây dựng như thế nào chưa? Bài viết của Nick Craver, Architecture Lead, Developer, Site Reliability Engineer & DBA Stack Overflow viết năm 2016 trên website của ổng sẽ bật mí cho chúng ta biết phía sau cô gái ấy có gì. Trong bài viết này mình sẽ tóm tắt lại những ý chính trong bài viết trên, chi tiết thì các bạn có thể theo dõi trực tiếp theo link phía trên nhé.
SO là 1 hệ thống khổng lồ, phục vụ hàng triệu người dùng, được thể hiện qua các con số biết nói như sau, số liệu vào năm 2016:
209,420,973 HTTP requests tới gateway ( load balancer)
66,294,789 page loads
1,240,266,346,053 bytes (1.24 TB) HTTP traffic gửi đến
569,449,470,023 bytes (569 GB) tổng nhận
3,084,303,599,266 bytes (3.08 TB) tổng gửi
504,816,843 SQL Queries (từ HTTP requests)
5,831,683,114 Redis hits
17,158,874 Elastic searches
3,661,134 Tag Engine requests
607,073,066 ms (168 hours) xử lý SQL queries
10,396,073 ms (2.8 hours) xử lý Redis hits
147,018,571 ms (40.8 hours) xử lý Tag Engine requests
1,609,944,301 ms (447 hours) xử lý trong ASP.Net
22.71 ms trung bình (19.12 ms trong ASP.Net) cho 49,180,275 truy cập trang câu hỏi
11.80 ms trung bình (8.81 ms trong ASP.Net) cho 6,370,076 truy cập trang home
Thật đáng kinh ngạc, để đạt được những con số này, thật không đơn giản, chúng ta cùng xem nhé. Bắt đầu nào!!
Dưới đây là sơ đồ logic tổng quan của hệ thống SO. Bao gồm:
“Everything is redundant” mọi thứ đều dư thừa là tôn chỉ của SO trong xây dựng hệ thống, luôn luôn là vậy trong mọi cài đặt.
Tất cả các server hay thiết bị mạng đều có tối thiểu 2x 10 Gbps cho card mạng.
Tất cả các server đều có 2 nguồn cấp điện thông qua 2 hệ thống UPS được hỗ trợ bởi 2 hệ thống cấp điện và 2 nguồn tiện ích khác.
Tất cả các server đều có dự phòng giữa 2 rack A và B.
Tất cả các server và dịch vụ đều có dự phòng ở datacenter khác (Colorado backup cho New York).
Kết nối Internets
Mỗi request khi truy cập vào trang web, sẽ đến với DNS đầu tiên, ta có thể thấy là stackoverflow.com được trỏ tới 4 ip .69 (có vẻ như mấy ổng thích con số này), truy cập nhanh chóng phục vụ cho toàn bộ user trên toàn thế giới, sử dụng CloudFlare làm DNS, tuy nhiên thì vẫn có những server chạy DNS dự phòng cho trường hợp có sự cố xảy ra.
Sau đó request sẽ đi đến từ 1 trong 4 nhà cung cấp mạng và đi qua 1 trong 4 router tương ứng. SO sử dụng đường truyền thì được cung cấp bởi 4 nhà mạng ISP tại New York đó là Level 3, Zayo, Cogent, và Lightower và sử dụng giao thức BGP để định tuyến. Tiếp đó sử dụng 2 cặp router ASR-1001 và ASR-1001-X và mỗi cái thì gắn 2 nhà mạng dưới dạng active/active và băng thông của mỗi line là 10Gbps.
Tiếp đó, request sẽ được đón nhận tại load balancer.
Haproxy
Haproxy được dùng làm load balancer, đang chạy version 1.5.15 trên Centos 7 và sẽ sớm chuyển sang version 1.7 có hỗ trợ http/2. Tất cả các traffic TLS(SSL) đều được chặn và xử lý tại đây.
Khác với những server khác, sử dụng 2 interface 10 GBps chạy LACP, thì server LB này có 1 interface dành cho external và 1 dành cho DMZ, có thể giải thích là 1 card public, 1 card private. Với bộ nhớ từ 64GB trở lên để cache lại TLS và SSL.
Việc cài đặt haproxy tương đối đơn giản, chỉ cần bắt đúng Host header và route chúng tới backend dựa trên ip và domain từ DNS.
Web Tier (IIS 8.5, ASP.Net MVC 5.2.3, và .Net 4.6.1)
Load balancer sẽ đá các request xuống 9 web server primary chạy production và 2 server phụ dành cho môi trường dev/staging. Các site trên IIS cụ thể cho 2 môi trường như sau:
Các web server như sau:
Service Tier (IIS, ASP.Net MVC 5.2.3, .Net 4.6.1, and HTTP.SYS)
Phía dưới của các web tier đó chính là các service chạy dưới IIS 8.5 trên Windows 2012 R2. Các serivce này chỉ chạy và xử lý nội bộ và phục vụ cho web server. Có 2 dịch vụ lớn đó là “Stack server” chạy trên HTTP.SYS và Providence API chạy trên IIS.
Bài viết ở trên còn nhiều trúc trắc do khả năng đọc hiểu của mình còn chưa tốt, nên mong nhận được sự góp ý của mọi người để mình có thể viết tốt hơn. Thanks.
Streaming hay streaming media là một quá trình mà các định dạng truyền thông (như âm thanh, hình ảnh) được gửi tới người dùng và hiển thị ngay cả khi nó vẫn đang trong quá trình tải.
2. Live streaming là gì ?
+ Đây là một thuật ngữ nói về việc các nội dung, các dữ liệu media được thu lại, xử lý rồi truyền tải trực tiếp qua mạng Internet tới người nhận trong cùng một thời điểm.
+ Vì là một kỹ thuật được thực hiện theo thời gian thực, nên tùy vào từng trường hợp, từng hệ thống server mà khi nhận được dữ liệu, video chạy trên thiết bị của người dùng sẽ có độ trễ nhất định so với các tình huống thực tế đang xảy ra. 3. Streaming video hay video streaming nghĩa là gì?
Video streaming chính là một “dòng chảy” video. Các thông tin, dữ liệu của đoạn video này được luân chuyển liên tục, đều đặn từ nguồn gửi tới “đích” nào đó thông qua mạng Internet.
3.1 Streaming video các tác dụng gì?
Điểm nổi bật và rõ ràng nhất của Stream video chính là việc người dùng có thể xem các đoạn video clip, thậm chí là phim mà không cần phải download về máy, điều này tiết kiệm được rất nhiều thời gian so với trước đây.
3.2 Streaming video hoạt động thế nào?
Hình ảnh minh họa đơn giản các hoạt động của live stream
Có thể hiểu Streaming Video chính là việc chia nhỏ các file media thành từng frame, sau đó gửi những frame này vào bộ nhớ đệm của máy tính và hiển thị nội dung lần lượt của từng fame. Trong khi người dùng đang sử dụng dữ liệu của những tập tin này thì frame của những tập tin khác vẫn tiếp tục được tải về.
II. Kiến trúc tổng quan HTTP Live Streaming
Hình ảnh minh họa cho kiến trúc HTTP Streaming
1. Server component
Server sẽ yêu cầu một phương thức để mã hóa các dữ liệu media đầu vào ( audio/video), sau đó sẽ phân đoạn các dữ liệu đó thành các segment và lưu chúng dưới dạng file
Media Encoder
+ Bộ mã hóa dữ liệu media sẽ lấy các tin hiệu realtime từ thiết bị audio-video sau đó mã hóa, đóng gói và vận chuyển các data segment từ nguồn tới đích , chuẩn mã hóa phải hỗ trợ những định dạng dữ liệu từ các thiết bị phía client, ví dụ như chuẩn H.264 cho video & chuẩn HE-AAC /MP3cho audio.
+ Hiện tại đã hỗ trợ MPEG-2, một tiêu chuẩn mã hóa nén(thường được gọi tắt là chuẩn nén) trong bộ tiêu chuẩn MPEG dùng để mã hóa luồng dữ liệu hình có kết hợp với các thông tin về âm thanh. Phiên bản trước của MPEG-2 là MPEG-1. MPEG-1 được thiết kế để truyền và lưu trữ các nội dung phim ảnh có độ phân giải trung bình (576×724 điểm ảnh).
Stream Segmenter
+ Stream Segmenter là một luồng xử lý thông qua 1 stream server ( nginx hoặc third-party software), đọc các luồng stream từ mạng local và phân chia thành các tệp media có kích thước nhỏ hơn.
+ Stream Segmenter cũng tạo ra một tập tin chỉ mục có chứa tham chiếu tới các tệp tin media riêng lẻ. Mỗi lần phân đoạn hoàn thành một tệp phương tiện mới, tệp chỉ mục sẽ được cập nhật. Chỉ mục được sử dụng để theo dõi sự sẵn có và vị trí của các tệp phương tiện.
+ Các segment media được lưu dưới dạng tệp .ts (tệp luồng vận chuyển MPEG-2). Các tệp chỉ mục được lưu dưới định dạng .M3U8.
2. Distribution component
+ Distribution system có thể hiểu là một web server hoặc là một cụm web caching system (CDN) cung cấp các media files & index files cho client thông qua giao thức HTTP
3. Client Component
+ Các thiết bị phía client ( moblie/destop/browser) sẽ đọc các index files dựa trên các url được định danh bởi các stream, Index files sẽ chỉ định vị trí của các tệp media đã có sẵn. Đối với các stream được chọn , client sẽ tải xuống từng tệp media có sẵn, mỗi tệp chứa một phân đoạn liên tiếp của luồng dữ liệu. Khi đã có đủ số lượng dữ liệu đã tải về, client có thể xem nội dung hiển từ các dữ liệu đó.
III. Một số giao thức chính sử dụng trong streaming
TCP/IP
+ RTP (Real Time Transport Protocol)
Giao thức vận chuyển thời gian thực đặc tả một tiêu chuẩn định dạng gói tin dùng để truyền âm thanh và hình ảnh qua internet. Tiêu chuẩn này được khai báo trong RFC 1889. Nó được phát triển bởi nhóm Audio Video Transport Working và được ban hành lần đầu tiên vào năm 1996.
RTP và RTCP liên kết rất chặt chẽ với nhau – RTP truyền dữ liệu thực trong khi RTCP được dùng để nhận thông tin phản hồi về chất lượng dịch vụ.
+ RTSP (Real Time Streaming Protocol)
– RTSP là một giao thức ở tầng ứng dụng trong bộ các giao thức Internet (Internet Protocol Suite) để kiểm soát việc truyền dữ liệu theo thời gian thực. RTSP cung cấp một nền tảng mở rộng cho phép kiểm soát, truyền theo yêu cầu của dữ liệu thời gian thực, chẳng hạn như âm thanh và video.
– RTSP được sử dụng để thiết lập và quản lý các phiên làm việc giữa các điểm truyền, phát tin đa phương tiện.
+ RTMP (Real Time Messaging Protocol)
– RTMP (Real Time Messaging Protocol) là giao thức không công khai do Adobe phát triển và giữ bản quyền, được thiết kế cho ứng dụng thời gian thực, cho phép ứng dụng sử dùng video và âm thanh với tốc độ nhanh, hạn chế bị giật hình hoặc méo tiếng.
HTTP
+ Apple HLS – HTTP Live Streaming
– Là một chuẩn giao thức cho HTTP Live Streaming được phát triển bởi Apple dành cho các thiết bị iOS và Quick Time Player, hỗ trợ Android 3.0. HLS có thể triển khai trên hầu hết các máy chủ HTTP ( bao gồm cả Apache) hoặc một số máy chủ streaming thương mại như Adobe FMS và Wowza.
+ HDS – Adobe HTTP Dynamic Streaming
– HTTP Dynamic Streaming được phát triển bởi Adobe như một sự thay thế cho giao thức RTMP của họ. HDS cho phép truyền trực tiếp trên HTTP tới bất kỳ thiết bị nào tương thích với Adobe Flash hoặc Air.
+ Microsoft Smooth Streaming
– Là một giao thức được phát triển bởi Microsoft dựa trên HTTP và chuẩn định dạng file mp4, bằng việc sử dụng các tài nguyên lưu trữ hiện có thông qua HTTP Caching.
+ DASH – Dynamic Adaptive Streaming over HTTP
– Là một kỹ thuật streaming cho phép truyển tải các nội dung media chất lượng cao qua Internet. Tương tự như giải pháp HTTP Live Streaming (HLS) của Apple, MPEG-DASH hoạt động bằng cách chia nhỏ nội dung thành một chuỗi các phân đoạn tệp dựa trên HTTP, mỗi phân đoạn chứa một khoảng thời gian phát khác nhau
*Sự khác biệt giữa 2 giao thức HTTP và RTMP
Giao thức HTTP
Giao thức RTMP
Web server (Apache, Lighttpd, Nginx…)
Messaging server (Adobe Flash Media Server, Wowza Media Server, Red5…)
Sử dụng Web Browser
Sử dụng Flash player
Truyền văn bản thời gian ngắn (Phù hợp với web truyền thống)
Truyền dữ liệu thời gian thực/dài (Phù hợp với các file Media: Nhạc, Phim)
SOAP, XML
AMF
File .html, .js
File .swf, .as, .flv, .mp3
IV. Cài đặt & cấu hình một streaming server
1. Cài đặt Nginx và Nginx-RTMP
$ yum -y install gcc gcc-c++ make zlib-devel pcre-devel openssl-devel
chunk_size 4096;#Kích thước chunk tối đa để ghép kênh stream
#video on demand for flv files
application vod {
play /var/flvs;
}
# video on demand for mp4 files
application vod2 {
play /var/mp4s;
}
### Tạo một luồng HLS streaming là hls ###
application hls {
live on; # Bật luồng streaming “live”
record all;# Bật ghi hình video và audio streaming
record_path /streaming/rec; # Thư mục chứa các file ghi hình flv
record_suffix _recorded.flv;
record_unique on; # Khi bật chế độ này sẽ thêm thời gian vào tên các file ghi hình
meta copy; # gửi đúng bản sao dữ liệu từ nguồn tới đích
interleave on; # Chuyển đổi chế độ xen kẽ. Trong chế độ này dữ liệu âm thanh và video được truyền trên cùng một đoạn RTMP.
wait_key on; #Tạo một video stream với một khung chính
wait_video on; # Disable audio cho đến khi video frame đầu tiên được gửi đi
hls on; # Bật hls
hls_fragment_slicing aligned; # chế độ này nhằm tạo ra các fragment giống nhau trên các instance nginx khác nhau
hls_path /streaming/hls; #Thiết lập thư mục chứa HLS playlist và fragment
hls_nested on; # Bật chế độ nested. Ở chế độ này một thư mục con sẽ được tạo ra cho mỗi luồng stream. Các HLS playlist và fragment sẽ được tạo ra trong thư mục con đó
hls_fragment 10s; # Thiết lập chiều dài HLS fragment
hls_playlist_length 5m; #Thiết lập chiều dài HLS cho playlist
hls_sync 100ms; # Set ngưỡng đồng bộ hóa thời gian HLS , tính năng này giảm tình trạng nhiễu âm sau khi chuyển đổi từ độ phân giải thấp RTMP (1KHz) sang độ phân giải cao MPEG-TS (90KHz).
hls_continuous on;
hls_cleanup off; # cho phép giữ lại các segment file .ts và index file .m3u8
hls_variant _240 BANDWIDTH=220000;
hls_variant _360 BANDWIDTH=1500000;
hls_variant _480 BANDWIDTH=2110000;
hls_variant _720 BANDWIDTH=3110000;
}
#allows you to play your recordings of your live streams using a URL like “rtmp://my-ip:1935/vod/filename.flv”
–Sử dụng module FFmpeg để encoding các live stream video về định dạng .flv và lưu ở thư mục /streaming/rec. Ta có thể tùy chỉnh các thông số như bitrate video, bitrate audio và độ phân giải.
Định dạng như sau: rtmp://ip-server:port/application-name/stream-name
-i: địa chỉ ứng dụng streaming.
-b: v bitrate video
-c: v bộ mã hóa hình ảnh
-s: độ phân giải
-f: định dạng xuất
-bufsize: kích thước bộ đệm
–Thêm vào nội dung sau trong file nginx.conf mục application hls{} :