PHÁT TRIỂN ỨNG DỤNG WEB VỚI SERVER-SIDE JAVASCRIPTNguyễn Tuấn Dũng Khóa QH-2008-I/CQ, ngành Công nghệ thông tin Tóm tắt Khóa luận tốt nghiệp: Ngày nay với kỉ nguyên công nghệ bùng nổ,
Trang 1ĐẠI HỌC QUỐC GIA HÀ NỘI TRƯỜNG ĐẠI HỌC CÔNG NGHỆ
Trang 2ĐẠI HỌC QUỐC GIA HÀ NỘI TRƯỜNG ĐẠI HỌC CÔNG NGHỆ
Trang 3LỜI CẢM ƠN
Lời đầu tiên, tôi xin gửi lời cảm ơn sâu sắc nhất tới Tiến sĩ Nguyễn Hải Châu, người đã tận tình hướng dẫn và giúp đỡ tôi trong suốt quá trình thực hiện khóa luận tốt nghiệp
Tôi chân thành cảm ơn các thầy, cô đã tạo những điều kiện thuận lợi cho tôi học tập và nghiên cứu tại trường Đại học Công nghệ Các thầy cô đã giảng dạy và cho tôi những kiến thức quý báu, làm nền tảng để tôi hoàn thành khóa luận cũng như công việc trong tương lai
Tôi cũng xin gửi lời tri ân tới các bạn trong lớp K53CC đã ủng hộ và giúp đỡ tôi trong suốt quá trình học tập tại trường
Cuối cùng, tôi muốn gửi lời cảm ơn vô hạn tới gia đình và bạn bè – những người thân yêu luôn ở bên, khuyến khích và động viên tôi trong cuộc sống cũng như trong học tập
Tôi xin chân thành cảm ơn
Hà nội, tháng 5 năm 2012 Sinh viên
Nguyễn Tuấn Dũng
Trang 4PHÁT TRIỂN ỨNG DỤNG WEB VỚI SERVER-SIDE JAVASCRIPT
Nguyễn Tuấn Dũng
Khóa QH-2008-I/CQ, ngành Công nghệ thông tin
Tóm tắt Khóa luận tốt nghiệp:
Ngày nay với kỉ nguyên công nghệ bùng nổ, thời kì của mạng xã hội đã khiến cho số lượng người dùng truy cập vào cùng một hệ thống ngày càng tăng.Điển hình như Facebook một ngày phục vụ hơn 1000 tỉ lượt xem với khoảng hơn 800 triệu lượt khách vào ra trong một tháng thì ta mới hình dung được sự bùng nổ của thông tin như thế nào.Để giải quyết vấn đề bùng nổ như trên thì chúng ta đã mở rộng các hệ thống máy chủ siêu lớn, phân thành nhiều các cụm đặt khắp nơi trên thế giới.Nhưng với tốc độ tăng trưởng theo cấp số hiện nay thì việc tăng số lượng máy chủ lên thôi có lẽ không đủ.Ta cần xem xét và nâng cấp các giải pháp xây dựng web cho tương lai Đầu tiên là về mặt ngôn ngữ và máy chủ.Các websever hiện hay với cách truyền thống là phục vụ theo luồng tự nó đã giới hạn khả năng của các máy chủ cho việc đáp ứng số lượng yêu cầu đến từ người dùng và không tốt cho các bài toàn cần tính toán thời gian thực.Giải pháp hướng sự kiện của nodeJS có vẻ khả khi trong trường hợp này.Nó sẽ giảm số luồng hoạt động của máy chủ xuống, giảm thời gian trễ nên đáp ứng rất tốt các ứng dụng thời gian thực.Ngoài ra việc tận dụng tốt hơn sẽ khiến cho số truy vấn đến nhiều hơn khiến cho việc giảm thiểu số máy chủ xuống
Thứ hai là về mặt cơ sở dữ liệu.Với các hệ thống với số lượng lên đến hàng triệu cho đến hàng tỉ thì việc hiệu năng tốt là việc bắt buộc.Hệ thống máy chủ cơ sở dữ liệu đòi hỏi phải rất mạnh mẽ nếu không máy chủ sẽ bị quá tải.Với các hệ RBDMs hiện nay thì vấn đề hiệu năng thường không tốt cho trường hợp này.Ngôn ngữ SQL là ngôn ngữ thông dịch với các ràng buộc trong các bảng khiến cho hiệu năng thực sự của hệ thống cơ sở dữ liệu khi thực thi là khá ì ạch với hệ thống lớn như kể trên.Chưa kể là với hệ thống lớn thì vấn đề phân tán dữ liệu, tính toàn vẹn dữ liệu là việc rất quan trọng.NoSQL đáp ứng được tất cả các yêu cầu này.Với tốc độ nhanh
do không phải qua các câu truy vấn SQL, có tính sẵn sàng, phân tán cao và độ ổn định tuyệt vời.Rất thích hợp cho các hệ thống có lượt truy vấn lớn.Ở trong khóa luận của tôi, tôi sẽ nghiên cứu về một NoSQL khá phổ biến - CouchDB.Với khả năng chịu lỗi tốt và tính ổn định cao, đồng
bộ giữa các thiết bị tốt, hỗ trợ các phiên bản khi offline tốt.CouchDB xứng đáng là một cơ sở dữ liệu đáng tin cậy
Từ khóa: Nodejs, javascript server side, nosql, couchdb
Trang 5LỜI CAM ĐOAN
Tôi xin cam đoan đây là công trình nghiên cứu và thực hiện khóa luận thực sự của riêng tôi, dưới sự hướng dẫn của ThS Nguyễn Hải Châu
Mọi tham khảo từ các tài liệu, công trình nghiên cứu liên quan trong nước và quốc
tế đều được trích dẫn rõ ràng trong luận văn Mọi sao chép không hợp lệ, vi phạm quy chế hay gian trá tôi xin hoàn toàn chịu trách nhiệm và chịu mọi kỷ luật của ĐHQG Hà
Nội và Nhà trường
Hà Nội, ngày 18 tháng 05 năm 2012
Sinh viên Nguyễn Tuấn Dũng
Trang 6MỤC LỤC
MỞ ĐẦU 1
CHƯƠNG 1: TÌM HIỂU VỀ NODE WEB: NODE.JS – THƯ VIỆN VIẾT ỨNG DỤNG SERVER-SIDE JAVASCRIPT 2
1.1 Javascript và lập trình server 2
1.2 NodeJs là gì? 2
1.3 Khác nhau giữa Blocking và Non-Blocking 3
1.3.1 Blocking 3
1.3.2 Non-Blocking 4
1.3.3 Lợi ích even-driven so với lại tốt hơn thread-driven 4
1.4 Node package manager (NPM) 7
1.4.1 Giới thiệu về NPM 7
1.4.2 Định dạng một gói cài npm 7
1.4.3 Sử dụng npm 8
1.4.4 Gói toàn cục và gói cục bộ trong khi npm cài đặt 9
Chương 2 TÌM HIỂU VỀ CÁC GIẢI PHÁP CƠ SỞ DỮ LIỆU DẠNG NOSQL (NOT ONLY SQL) 10
2.4 Đặc điểm của NoSQL? 11
2.5 Phân loại NoSQL? 12
2.5.1 Wide Column Store / Column Families 12
2.5.2 Key-Value Store/Tuple store 12
2.5.3 Document Store 12
2.5.4 Graph Database 13
2.6 Hiệu năng NoSQL 13
2.6.1 Xử lý việc suy giảm hiệu năng 13
2.6.2 Xử lý một dữ liệu cực lớn 14
2.7 Các loại NoSQL phổ biến 15
2.7.1 MongoDB [2][3] 15
2.7.2 CouchDB [4] 16
2.7.3 Cassandra[5] 17
2.7.4 Membase [6] 19
Trang 7Chương 3 TÌM HIỂU VỀ COUCHDB 20
3.1 CouchDB là gì 20
3.2 Lịch sử CouchDB 20
3.3 Các đặc điểm của CouchDB 20
3.3.1 Document storage 21
3.3.2 Map/Reduce Views và Indexes 21
3.3.3 Kiến trúc phân tán với việc nhân bản [10] [11] 21
3.3.4 REST API 22
3.3.5 Tính nhất quán cuối cùng 23
3.3.6 Sử dụng Offline 23
3.4 Sử dụng CouchDB 23
3.4.1 Khởi động 23
3.4.2 Xử lý truy vấn trong CouchDB 23
3.4.3 Views 24
3.4.6 Futon 28
3.5 Tìm hiểu phần mở rộng GEO của COUCHDB 29
3.5.1 GeoCouch là gì 29
3.5.2 Cài đặt GeoCouch 30
3.5.3 Kết nối NodeJs và GeoCouch 31
3.5.4 Sử dụng GeoCouch 31
Chương 4 ỨNG DỤNG MAPCHAT 33
4.1 ExpressJS 33
4.2 SocketIO 34
4.3 Cài đặt project 35
4.3.1 Phần Chatting 35
4.3.2 Phần map 36
KẾT LUẬN 39
Trang 8DANH SÁCH CÁC BẢNG
Bảng 1: So sánh CSDL quan hệ và NoSQL……… 11 Bảng 2: Bảng tương ứng các câu lệnh truy vấn …… ………23
Trang 9DANH SÁCH CÁC HÌNH VẼ
Hình 1:Bảng so sánh hiệu n……….13
Hình 2: Giao diện Futon………28
Hình 3: Tạo temporary view……….29
Hình 4: Ứng dụng mapchat……… 38
Trang 10DANH SÁCH CÁC TỪ VIẾT TẮT
Từ viết tắt Nghĩa của từ viết tắt
API Application on Programming Interface ACID Atomicity, Consistency, Isolation, Durability
Trang 11MỞ ĐẦU
Ngày nay với kỉ nguyên công nghệ bùng nổ, thời kì của mạng xã hội đã khiến cho số lượng người dùng truy cập vào cùng một hệ thống ngày càng tăng Điển hình như Facebook một ngày phục vụ hơn 1000 tỉ lượt xem với khoảng hơn 800 triệu lượt khách vào ra trong một tháng thì ta mới hình dung được sự bùng nổ của thông tin như thế nào
Để giải quyết vấn đề bùng nổ như trên thì chúng ta đã mở rộng các hệ thống máy chủ siêu lớn, phân thành nhiều các cụm đặt khắp nơi trên thế giới Nhưng với tốc độ tăng trưởng theo cấp số hiện nay thì việc tăng số lượng máy chủ lên thôi có lẽ không đủ Ta cần xem xét và nâng cấp các giải pháp xây dựng web cho tương lai
Chương 1: Tìm hiểu về node web: node js – Thư viện viết ứng dụng server-side
javascript có khả năng chạy được trên server Chúng ta sẽ giới thiệu qua về cách hoạt
động, các đặc điểm của nó và điểm mạnh điểm yếu của bộ thư viện này
Chương 2: Tìm hiểu về các giải pháp CSDL dạng NoSQL (Not-Only-SQL) Chương này giới thiệu cho chúng ta tổng quan về khái niệm NoSQL, các đặc điểm nổi bật của nó So sánh tương quan giữa NoSQL và SQL truyền thống Từ đó đưa ra được các
giải pháp cho các trường hợp nào nên dùng NoSQL
Chương 3: Tìm hiểu về CouchDB Chương này giới thiệu về một NoSQL khá phổ biến hiện nay - CouchDB Nêu ra đặc điểm, điểm yếu mạnh và cách dùng cơ bản của nó
sẽ tìm hiểu về một phần mở rộng của CouchDB có khả năng hỗ trợ các định dạng địa lý như điểm, vecto v v đó là GeoCouch.Sẽ hướng dẫn cách dùng và cách sử dụng cơ bản
của nó
Kết luận: NoSQL và Javscript server side có thể sẽ là tương lai của web trong một
tương lai không xa Khi mà yêu cầu về tốc độ, thống nhất ngôn ngữ, tính sẵn sàng và khả
năng mở rộng cao được đặt lên hàng đầu
Trang 12CHƯƠNG 1: TÌM HIỂU VỀ NODE WEB: NODE.JS – THƯ VIỆN VIẾT ỨNG
DỤNG SERVER-SIDE JAVASCRIPT
1.1 Javascript và lập trình server
Mặc dù các ứng dụng trên nền web chở nên phổ biến trong những năm gần đây, nhưng chúng vẫn rất khó để phát triển, duy trì và mở rộng Nhiều thách thức ở đây là việc ngăn cách giữa các thành phần client và server Các thành phần phía client thường được
sử dụng bao gồm HTML, CSS, Javascript, Ajax(một phần của javascript), ảnh và các file
mà ta có thể tải về từ trình duyệt Phía server, thì ta cần lắng nghe từ các yêu cầu, xuất ra tài nguyên hoặc thông tin và thao tác với chúng để chúng có thể gửi trả về phía client Điều này thường được thực hiện bằng cách sử dụng XML, JSON hoặc là định dạng theo kiểu HTML, cái mà gửi thông qua đường truyền sử dụng Ajax Ta có vô số các công nghệ cạnh tranh được chọn ở đây Phụ thuộc vào đường truyền, phần cứng, hệ điều hành, băng thông, chuyên môn công nghệ và vô vàn các yếu tố khác Mỗi một công nghệ mang lại một trải nghiệm khác nhau Các ngôn ngữ phía server được dùng phổ biến đến bây giờ là PHP, java và NET
Điều này dẫn đến việc cần có một chuẩn để thống nhất lập trình giữa server và client Và phong trào ServerJS với mục đích ra xóa bỏ hàng rào ngăn cách giữa client và server Họ tìm cách giữ lại các thành phần chủ đạo và tìm điểm chung cho client và server Các thành phần được giữ lại là HTML, javscript và CSS, cái mà đã quá quen thuộc với người dùng cuối Còn về phía server Họ xây dựng server dựa theo Javascript có thể làm web server và nhiều hơn thế nữa Rất nhiều dịch vụ server được viết bằng JavaScript
đã ra đời ví dụ như Jaxer được phát triển bởi Aptana, Jaxer là một web serve dựa Ajax
để xây dựng một trang web nhiều tính năng cũng như các ứng dụng sử dụng mô hình ajax cái có thể được viết hoàn toàn bằng JavaScirpt
Chúng ta sẽ tập trung vào một Javascript-server-side khác: Nodejs
1.2 NodeJs là gì?
Javascript trước đây chỉ chạy được trên trình duyệt web Nhưng gần đây nó được dùng ở phía server Có những môi trường Javascript ở phía server như là Jaxer và Narwhal, tuy nhiên Nodejs có một chút khác biệt so với những cái trên Bởi vì nó dựa trên
sự kiện hơn là dựa theo luồng (thread) Các máy chủ Web như Apache thường sử lý PHP
và các script CGI khác dựa theo luồng bởi chúng sinh ra một hệ thống luồng cho mỗi request đến Trong khi cách đó là ổn cho rất nhiều ứng dụng thì các mô hình dựa theo
Trang 13luồng không thể mở rộng một cách có hiệu quả với nhiều kết nối tồn tại lâu Ví dụ như bạn muốn dùng các dịch vụ thời gian thực như Friendfeed hay Google Wave
Nodejs, sử dụng một sự kiện lặp thay cho các luồng, và nó có thể mở rộng lên hàng triệu kết nối một lúc Điều này rất có lợi vì thực tế các máy chủ sử dụng phần lớn thờti gian vào việc đợi các xử lý vào ra (ví dụ như đọc một file từ ổ cứng, truy vấn đến một dịch vụ web bên ngoài hoặc là đợi file được tải lên hoàn tất) bởi vì các xử lý đó chậm hơn rất nhiều so với xử lý bộ nhớ Với kiến trúc hướng sự kiện thì lượng bộ nhớ dùng ít hơn, lưu nượng tăng cao và mô hình lập trình thì đơn giản hơn
Mỗi một xử lý vào ra trong Nodejs là không đồng bộ, nghĩa là máy chủ có thể tiếp tục sử lý các request đến trong khi các sử lý vào ra đang diễn ra Javascript mà một ngôn ngữ phù hợp cho việc lập trình hướng sự kiện bởi vì nó có các hàm không đồng bộ và sự bao đống cái mà tạo ra một hàm callbacks đảm bảo Và lập trình viên Javascript thì đã biết cách lập trình theo cách này rồi Mô hình hướng sự kiện khiến cho Nodejs chạy rất nhanh và có thể triển khai và mở rộng cho các ứng dụng thời gian thực một cách dễ dàng Một lợi ích lớn lao của NodeJS đó là nó được viết bằng javascript Nó cũng hỗ trợ các hệ NoSQL dùng javascript để truy vấn Từ đây ta chỉ cần học một ngôn ngữ là javascript để thực thi từ phía trình duyệt, phía webserver và cả cho database server
1.3 Khác nhau giữa Blocking và Non-Blocking
1.3.1 Blocking
Theo cách truyền thống (thread-based) thì hãy tưởng tượng một ngân hàng đang áp dụng mô hình phục vụ:Phục vụ hoàn toàn một yê u cầu rồi mới chuyển sang yêu cầu khác Trong đó nhân viên trong ngân hàng Tương ứng mỗi nhân viên là một Thread Và mỗi một yêu cầu tương ứng là 1 request đến server Bạn yêu cầu là muốn gửi tiền vào ngân hàng Bạn sẽ phải điền 1 số form như tên người gửi, số tài khoản của họ, số tiền cần gửi v v Trong thời gian bạn điền thông tin cần rút tiền vào tờ khai Cô nhân viên phải chờ bạn Bạn đã "khóa" cô ấy không cho cô ấy phục vụ các khách hàng khác vì lúc đó cô
ấy đang rảnh vì phải đợi bạn Hành động đợi ở đây phần lớn là hành động vào/ra, truy
suất file, hoặc đợi kết quả truy vấn SQL trong Webservice Đó là cơ chế Blocking
Theo cách này Nếu ngân hàng đang quá tải vì có quá nhiều người chờ được phục
vụ Thì ngân hàng chỉ còn một cách duy nhất là Tăng thêm số nhân viên phục vụ lên Ở trường hợp này trong ví dụ chúng ta là tăng số server phục vụ lên
Trang 14Vấn đề xảy ra ở đây ra Khi tăng số lượng nhân viên lên để đáp ứng nhu cầu phục vụ khách hàng thì ngân hàng phải tăng chi phí (tiền để trả lương, mặt bằng văn phòng ) (tương ứng với việc tăng phần cứng máy chủ lên để đáp ứng) Như thế sẽ gây ra các vấn
đề về lãng phí Và không tận dụng được nguồn lực và tiết kiệm được chi phí
1.3.2 Non-Blocking
Ở một ngân hàng khác, họ lại áp dụng theo một phương thức mới driven):Tận dụng mọi khả năng của tất cả các nhân viên khi họ rảnh và nhân viên khi có yêu cầu mới phục vụ.Tức là khi bạn có một yêu cầu muốn gửi tiền như ở trên Cô nhân viên chỉ cần đưa bạn bút và giấy để bạn điền vào và bảo bạn hãy ngồi ở ghế chờ để điền xong thông tin gửi tiền Trong khi đó cô ấy có thể phục vụ những vị khách tiếp theo Ở đây bạn đã không "khóa" cô ấy lại Và cô nhân viên tranh thủ lúc đợi bạn điền các thông tin Cô ấy có thể làm việc khác Thành ra ở đây không có hành động đợi vô nghĩa ở đây Khi bạn điền xong thông tin, bạn có thể trở lại gặp cô ấy báo là đã hoàn thành Cô ấy sẽ
(event-tiếp tục phục vụ bạn để bạn hoàn thành việc của mình Đây là cơ chế Non-Blocking
Bạn có thể thấy, theo mô hình áp dụng của ngân hàng này (event-driven), họ sẽ tận dụng được khoảng thời gian rỗi của nhân viên Khiến cho việc một nhân viên có thể phục
vụ nhiều khách hàng hơn so với ngân hàng dùng mô hình theo cách cũ ở trên Nếu có quá tải Bạn chắc chắn vẫn phải thêm nhân viên để đáp ứng kịp thời Nhưng chắc chắn sẽ thêm ít nhân viên hơn Tiết kiệm được rất nhiều tài nguyên (Đây cũng là mô hình được
áp dụng phổ biến ở các ngân hàng)
1.3.3 Lợi ích even-driven so với lại tốt hơn thread-driven
Nói đến đây, chắc chắn sẽ có một vài câu hỏi được đặt ra:
- Mặc định, Nodejs chỉ có một luồng được thực thi Nó không cần đợi các tác vụ vào ra hoặc là chuyển nội dung Thay vào đó, các tác vụ vào/ra sẽ tự động tạo
ra một hàm điều khiển gửi tới các sự kiện khi mà mọi thứ đã xong Các sự kiện lặp và mô hình điều hướng lặp cũng giống như cách mà javascript ở phía trình duyệt thực hiện Chương trình sẽ xử lý các hành động và nhanh chóng quay về vòng lặp để gửi các tác vụ khác đến Khi load 1 trang và đang chờ nó truy xuất
cơ sở dữ liệu, thì nodejs sẽ tranh thủ phục vụ request khác Trong khi việc chờ truy xuất cơ sở dữ liệu vẫn tiếp tục Vậy cũng thể coi đó là 2 tiến trình hoàn tòan khác nhau
Trang 15- Ngay trong hệ điều hành đã áp dụng mô hình dựa theo sự kiện (event-based) rồi Nó sẽ không chỉ có 1 thread mà sẽ có rất nhiều thread Và khi 1 thread tiến trình đang bị blocking I/O Thì hệ điều hành sẽ cho các thread khác được chạy thay thế Và như thế sẽ không có thời gian trễ Như vậy sẽ không có lợi ích gì đáng kể của mô hình hướng sự kiện so với không hướng sự kiện
Có thể trả lời 2 câu hỏi trên như sau bằng 1 ví dụ: (Ở đây ta sẽ so sánh Nodejs với Apache)
1 đoạn code sau:
result = query( "select A from B" );
do_something(result);
Theo cách thông thường như trên Nếu một request được gửi đến yêu cầu xử lý đoạn code trên Webservice sẽ phải tạo ra 1 thread để xử lý Vấn đề là thread được tạo ra đó sẽ không làm gì cả trong khi hàm query() vẫn đang chạy Cho đến khi kết quả của câu lệnh truy vấn SQL trên xử lý thành công, lâu hay nhanh thì tùy thuộc vào độ phức tạp của câu truy vấn Sau đó thread sẽ gọi hàm do_something Đó thực sự không tốt bởi vì trong khi toàn bộ các tiến trình đang trong trạng thái đợi(trừ tiến trình SQL) thì các yêu cầu mới vẫn tiếp tục được gửi đến Lúc này sẽ sinh ra rất nhiều các tiến trình đang đợi thực thi câu lệnh, theo đúng cơ chế Blocking, vẫn ngốn tài nguyên máy chủ nhưng không làm gì cả
Và nếu tất cả các tiến trình nhiều đến mức ngốn hết tài nguyên trong khi các tác vụ vẫn chưa xong vì phải đợi thì lúc đó hệ thống sẽ sụp đổ Quả thực là rất lãng phí Mà việc chuyển trạng thái giữa các tiến trình là luôn có một khoảng thời gian trễ nào đó, mà càng nhiều tiến trình thì CPU càng mất nhiều thời gian để lưu trữ và khởi động lại các trạng thái, kéo theo tổng thời gian trễ đợi chuyển giữa các tiến trình là tăng lên Đơn giản bằng cách không đồng bộ, Node sẽ tận dụng triệt để tài nguyên do không có tài nguyên nào phải đợi lãng phí nữa
Một điểm yếu của lập trình hướng luồng là việc đồng bộ và tính đồng nhất của nó
Độ phức tạp của nó đến từ việc trao đổi giữa các biến và các hàm để tránh việc deadlock
và xung đột giữa các luồng với nhau
Node khiến cho chúng ta phải hiểu theo một nghĩa khác thế nào là đồng nhất Các hàm callback được gọi một cách không đồng bộ trong các sự kiện lặp xử lý khá tốt trong việc đồng nhất, khiến cho mô hình đồng nhất trở nên đơn giản hơn, dễ hiễu hơn và dễ
Trang 16thực hiện hơn Nhất là khi với việc trễ trong truy xuất các đối tượng Nếu truy suất trong
bộ nhớ thì ta chỉ mất với thời gian là nano giây, truy suất đĩa cứng hoặc qua mạng cục bộ thì có thể mất thời gian là mili giây hoặc thậm trí cả giây Nhưng việc truy suất đó chưa hẳn đã xong, sẽ còn khá nhiều các tác vụ khác nữa trước khi được đưa đến người dùng cuối, họ sẽ phải chờ rất nhiều thời gian để kết quả có thể hiện ra
Còn với NodeJs thì câu truy vấn sẽ như thế này:
query(statement: "select A from B", function(result){
// Xu ly ket qua sau khi tra ve do_something();
} );
Theo cách viết dưới thì nó, tức nodejs, sẽ báo cho môi trường hoạt động (ở đây là
OS và webserver) là khi nào cần tạo tiến trình và phải làm gì Đơn giản ở trên đoạn viết trên, chương trình vẫn sẽ tạo ra một thread và sẽ báo là khi nếu có câu truy vấn query() thì chương trình sẽ đợi hàm đó chạy xong Trong lúc đợi query() chạy nó có thể phục vụ các truy vấn khác Khi nào query() truy vấn cơ sở dữ liệu xong Chương trình sẽ quay trở lại gọi lại hàm callback ở trên là do_something() Do đó, thread đó sẽ không phải đợi Việc tính toán giữa nhiều request có thể thực hiện một cách song song
Cách viết code ở trên thực hiện y hệt như code ở phía trước nữa thực hiện Chỉ có điểm khác biệt là kết quả của việc truy vấn không phải là trả về kết quả truy vấn mà là trả
về 1 hàm callback sẽ được thực thi sau khi truy vấn được thực thi hoàn toàn Lúc này khi sau khi truy vấn được thực thi xong.Ta có thể toàn quyền xử lý với kết quả trả về, đặt thêm các sự kiện khác đến với nó Ta có thể thấy event-driven khá giống với lập trình socket
Tóm lại, sức mạnh của nodejs không dựa vào vòng lặp bắt sự kiện của nó hoặc là đồng bộ vào/ra mà lại dựa vào hệ thống callback của nó đã làm giảm rất nhiều thời gian
chờ của hệ thống
Trang 171.4 Node package manager (NPM)
1.4.1 Giới thiệu về NPM
Được viết tắt bởi Node Package Manager (Trình quản lý gói của nodejs) Nó vừa là một trình quản lý gói vừa là một hệ thống phân tán phục vụ cho NodeJs Mục đích chính của nó là tạo ra và phân phối các gói Node, các module qua internet sử dụng dòng lệnh Với npm chúng ta có thể dễ dàng tìm các module một cách tự động qua mạng Chỉ với
một câu lệnh, ta có thể tải, cài và sử dụng các module
1.4.2 Định dạng một gói cài npm
Một gói cài npm miêu tả trúc thư mục của nó ở trong file package.json Nó bao gồm tên gói, phiên bản, cấu trúc các cấp của thư mục bên trong gói cài, các module nào cần thiết, phụ thuộc cần phải cài trước
Một file package.json đơn giản nhất sẽ có cấu trúc như dưới:
{ name: "PackageA", version: "1.0", main: "mainModuleName", modules: {
"module1": "abc/module1", "module2": "abc/module2"
} }
Hai thẻ quan trọng nhất trong file này là thẻ name và thẻ version Thẻ name sẽ miêu
tả tên của gói và được dùng để tìm gói dễ dàng hơn
#npm search packageName
Ở đây package name chính là tên trong thẻ name Thẻ version là thẻ khai báo tên phiên bản của gói cài Mặc định npm nếu không có các tham số nó sẽ tải gói cài với phiên bản mới nhất
Trang 18Trong một module trong NodeJs cũng có thể đi kèm các module phụ thuộc nó Khai báo trong file json thì npm sẽ tự động cài các module khác đi kèm với module đó Khai báo các gói phụ thuộc nhƣ sau
"dependencies":
{ "one": "1.0 - 2.5"
"two": ">= 0.9 <2.3"
} Ngoài ra còn các tham số khác:
"description": "module của tôi"
Nhƣng nếu bạn không nhớ đầy đủ tên module mà chỉ nhớ một phần tên thì sao
Ngoài việc vào trang http://search.npmjs.org thì bạn có thể dùng npm để cài
Nếu muốn tìm chi tiết hơn ví dụ là tìm trang chủ hay phiên bản của module:
#npm view moduleName version
Trang 191.4.4 Gói toàn cục và gói cục bộ trong khi npm cài đặt
Mặc định khi dùng câu lệnh install trong npm sẽ là cài 1 gói ở dạng local, tức là nó
chỉ có tác dụng trên thư mục mình cài
Ví dụ tại thư mục nodejs/dirA/ có gói là testcase
cd nodejs/dirA/
npm install testcase
Trong thư mục nodejs/dirB/ ta tạo 1 file.js có gọi gói testcase
var HTTPServer = require('testcase');
Thì sẽ báo lỗi không tìm thấy gói testcase, vì gói testcase ta install nó trong thư mục dirA, nên npm sẽ hiểu testcase là gói cục bộ trong thư mục dirA
Để có thể dùng gói testcase trong dirB ta có thể dùng 2 cách sau:
Cục bộ:Ta vào lại thư mục dirB và cài lại gói testcase bằng npm, lúc
đó gói testcase sẽ là gói cục bộ trong thư mục dirB
cd anotherapp/
npm install http-server
Toàn cục:Ta sẽ cài gói testcase là 1 gói toàn cục Tức là bất cứ thư
mục nào (kể cả không phả dirA và dirB cũng có thể gọi gói testcase được
#npm install http-server -g
Mặc định thì npm cài thêm module theo cách cục bộ tức là nó sẽ cài vào mục node_modules tại thư mục hiện thời Để thay đổi việc cài module sao cho khi cài npm sẽ mặc định sẽ cài vào toàn cục Đây là cách mà các chương trình có thể dùng các module
toàn cục mà không cần cài thêm
#npm set global=true
Để kiểm tra xem biến global đã được set chưa ta dùng tham số get
#npm get global
Trang 20Chương 2 TÌM HIỂU VỀ CÁC GIẢI PHÁP CƠ SỞ DỮ LIỆU DẠNG NOSQL (NOT ONLY SQL)
2.1 NoSQL là gì ?
noSQL, viết tắt của non-relational, hoặc theo cách hiểu khác thì có nghĩa là Not only SQL (không chỉ là SQL) NoSQL đặc biệt nhấn mạnh đến mô hình lưu trữ cặp giá trị - khóa và hệ thống lưu trữ phân tán
Hệ CSDL này có thể lưu trữ, xử lý từ lượng rất nhỏ đến hàng petabytes dữ liệu với khả năng chịu tải, chịu lỗi cao nhưng chỉ đòi hỏi về tài nguyên phần cứng thấp NoSQL thiết kế đơn giản, nhẹ, gọn hơn so với RDBMs, thiết kế đặc biệt tối ưu về hiệu suất, tác
vụ đọc-ghi, ít đòi hỏi về phần cứng mạnh và đồng nhất, dễ dàng thêm bớt các node
không ảnh hưởng tới toàn hệ thống, …
Về cơ bản, các thiết kế của NoSQL lựa chọn mô hình lưu trữ tập dữ liệu theo cặp giá trị key-value Khái niệm node được sử dụng trong quản lý dữ liệu phân tán Với các
hệ thống phân tán, việc lưu trữ có chấp nhận trùng lặp dữ liệu Một request truy vấn tới data có thể gửi tới nhiều máy cùng lúc, khi một máy nào nó bị chết cũng không ảnh hưởng nhiều tới toàn bộ hệ thống Để đảm bảo tính real time trong các hệ thống xử lý lượng lớn, thông thường người ta sẽ tách biệt database ra làm 2 hoặc nhiều database Một database nhỏ đảm bảo vào ra liên tục, khi đạt tới ngưỡng thời gian hoặc dung lượng, database nhỏ sẽ được gộp (merge) vào database lớn có thiết kế tối ưu cho phép đọc (read operation) Mô hình đó cho phép tăng cường hiệu suất I/O - một trong những nguyên
nhân chính khiến performance trở nên kém
2.3 Bảng so sánh
Trang 21Có quan hệ giữa các bảng
Tốt với một mô hình sử lý theo lô (batch process) và tối ưu về đọc ghi dữ liệu
Thay đổi
số node trong
hệ thống
Phải tắt cả hệ thống.Việc thay đổi số node phức tạp
Không cần phải tắt cả hệ thống.Việc thay đổi số node thường khá đơn giản, không ảnh hưởng đến hệ thống
2.4 Đặc điểm của NoSQL?
- Phi quan hệ (hay không ràng buộc): Các mối quan hệ giữa các bảng trong cơ sở
dữ liệu quan hệ (RDBM) sử dụng mô hình gồm 2 loại khóa: khóa chính và khóa phụ (primary key + foreign key) để ràng buộc dữ liệu nhằm thể hiện tính nhất quán dữ liệu từ các bảng khác nhau Non-relational là khái niệm không sử dụng các ràng buộc dữ liệu cho nhất quán dữ liệu
- Lưu trữ phân tán: mô hình lưu trữ phân tán các tập tin hoặc dữ liệu ra nhiều máy khác nhau trong mạng LAN hoặc Internet dưới sự kiểm soát của phần mềm
Trang 22- Nhất quán cuối: tính nhất quán của dữ liệu không cần phải đảm bảo ngay tức khắc sau mỗi phép ghi Một hệ thống phân tán chấp nhận những ảnh hưởng theo phương thức lan truyền và sau một khoảng thời gian (không phải ngay tức khắc), thay đổi sẽ
đi đến mọi điểm trong hệ thống để cuối cùng dữ liệu trên hệ thống sẽ trở lại trạng thái nhất quán
- Triển khai đơn giản, dễ nâng cấp và mở rộng
- Mô hình dữ liệu và truy vấn linh hoạt …
2.5 Phân loại NoSQL?
2.5.1 Wide Column Store / Column Families
Hệ cơ sở dữ liệu phân tán cho phép truy xuất ngẫu nhiên/tức thời với khả năng lưu trữ một lượng cực lớn data có cấu trúc Dữ liệu có thể tồn tại dạng bảng với hàng tỷ bản ghi và mỗi bản ghi có thể chứa hàng triệu cột Một triển khai từ vài trăm cho tới hàng nghìn commodity hardware dẫn đến khả năng lưu trữ hàng petabytes nhưng vẫn đảm bảo high performance Dưới đây là một số sản phẩm thông dụng: Hadoop/HBase – Apache, BigTable – Google, Cassandra - Facebook/Apache, Hypertable - Zvents Inc/Baidu, Cloudera, SciDB, Mnesia, Tablets, …
2.5.2 Key-Value Store/Tuple store
Mô hình lưu trữ dữ liệu dưới cặp giá trị key-value trong đó việc truy xuất, xóa, cập nhật giá trị thực thông qua key tương ứng Với sự bổ trợ bởi các kỹ thuật BTree, B+Tree, Hash, dữ liệu có thể tồn tại trên RAM hoặc đĩa cứng, phân tán hoặc không phân tán Hầu hết các NoSQL database đều là key-value store
2.5.3 Document Store
Thực chất là các document-oriented database - một thiết kế riêng biệt cho việc lưu trữ document Các cài đặt có thể là giả lập tương tác trên relational database, object database hay key-value store Một số sản phẩm tiêu biểu: Apache Jackrabbit, CouchDB, IBM Lotus Notes Storage Format (NSF), MongoDB, Terrastore, ThruDB, OrientDB, RavenDB,
CouchDB là cơ sở dữ liệu thuộc nhánh document store
Trang 232.5.4 Graph Database
Graph database là một dạng cơ sở dữ liệu được thiết kế riêng cho việc lưu trữ thông tin đồ họa như cạnh, nút, properties Một số sản phẩm tiêu biểu: Neo4J, Sones, AllegroGraph, Core Data, DEX, FlockDB, InfoGrid, OpenLink Virtuoso,
2.6 Hiệu năng NoSQL
Hình 1:Bảng so sánh hiệu n
2.6.1 Xử lý việc suy giảm hiệu năng
NoSQL không dùng các câu lệnh thông dịch SQL và các truy vấn rườm rà khác khiến nó cho ta một kiến trúc tối ưu về tốc độ thực thi (Đọc và ghi và cập nhật dữ liệu).Các câu lệnh SQL khá dễ đọc dễ hiểu.Nhưng nếu dữ liệu các đơn giản, các thủ tục SQL sẽ không cần thiết Nhưng với các dữ liệu không có một cấu trúc cố định - ví dụ như
- bài viết chẳng hạn, có rất nhiều kiểu bài viết, mỗi một kiểu bài viết lại có rất nhiều trường đi riêng biệt dành riêng cho nó.Tin tức thời sự chỉ có 3 trường là Tiêu đề, miêu tả,
và phần thân, nhưng với văn bản pháp luật thì ngoài 3 trường trên còn có thêm trường cho phép đính kèm file văn bản pháp luật sửa đổi mới Việc lưu trữ và truy vấn lấy các bài viết dạng thế này phải dùng khá nhiều câu lệnh join Càng nhiều câu lệnh Join thì hiệu năng càng giảm
Không như SQL, NoSQL lưu tất cả các trường tập trung vào trong một phần tử là document, các document này không nhất thiết phải bị "ràng buộc" phải có các trường
Trang 24giống nhau, nên sẽ có các phần tử có nhiều trường hơn các phần tử khác.Các khái niệm khóa ngoại khóa chính sẽ được loại bỏ - vì các document không còn quan hệ với nhau.Các bài viết được phân biệt với nhau bởi trường id.Đến lúc này khi truy vấn bài viết nào đó thì ta chỉ việc truy vấn thẳng đến document đó là có thể lấy chính xác tất cả dữ liệu cần tìm khiến cho hiệu năng truy vấn tăng lên đáng kể
2.6.2 Xử lý một dữ liệu cực lớn
NoSQL được thiết kế cho việc lưu trữ dữ liệu phân tán cho các dữ liệu cực lớn.Một
ví dụ rất quen thuộc ở đây là Facebook với trên 600 triệu người dùng đang truy cập hàng ngày, hàng ngàn tetra ảnh được tải lên mỗi ngày thì ta mới biết nó khủng khiếp sao.Tất nhiên không có máy chủ nào có thể xử lý được khối dữ liệu khổng lồ đó.Ta phải tách nó
ra làm nhiều cụm máy chủ lớn khác nhau gọi là Data Center.Và cũng không thể chỉ có một Data Center có thể thực hiện được công việc như trên.Ta lại chia ra làm các cụm Data Center.Với nhiều máy chủ như vậy.Đòi hỏi việc phân tán dữ liệu như thế nào, quản lý ra sao, tốc độ cập nhật thế nào là điều cực kỳ quan trọng.NoSQL đáp ứng được những yêu cầu này
Với cơ sở dữ liệu dạng NoSQL, thì không có cấu trúc và không có các câu lệnh nối Một RDBMs truyền thống thì muốn mở rộng, nâng cấp thì chỉ có cách là nâng cấp phần cứng mới hơn, mạnh hơn, mua thêm nhiều máy chủ tập trung thật tốt.Còn với NoSQL, ngoài cách đó ra thì nó còn mở rộng theo chiều khác nữa, đó là nó có khả năng lan truyền đều trên toàn hệ thống, tức là có thể giữa các Datacenter với nhau chứ không chỉ riêng mỗi Datacenter Đây là một giải pháp ít tốn kém hơn so với RDBMs, tận dụng được nguồn tài nguyên nhàn rỗi tốt hơn
Dưới đây là các lĩnh vực mà NoSQL đóng một vai trò khá quan trọng và cần thiết:
Lưu trữ dữ liệu: Tổng dữ liệu số hiện nay đã được lưu bằng đơn vị exabytes.Một exabyte tương đương với 1 tỉ GB dữ liệu.Theo một số liệu nghiên cứu của trang Internet.com(*) thì tổng lưu lượng internet năm 2006 vào khoảng 161 exabytes.Và chỉ 4 năm sau là vào năm 2010 thì tổng lượng dữ liệu internet là khoảng 1000 exabyte, tăng hơn 500%.Và vì vậy, dữ liệu được lưu trữ ngày càng lớn lên
Dữ liệu được kết nối: Dữ liệu ngày càng trở nên "kết nối" hơn, tức là các trang web này có liên kết các trang web kia, các mạng xã hội tương tác
Trang 25người dùng với nhau.Và các hệ thống cũng được xây dựng để tương tác với người dùng
Cấu trúc dữ liệu phức tạp.NoSQL có thể kiểm soát cấu trúc dữ liệu phân thành nhiều cấp một cách dễ dàng.Để thực hiện một công việc tương tự như vậy trong SQL thì ta phải tạo rất nhiều bảng để lưu trữ với rất nhiều khóa ngoại, kéo theo đó là tốc độ khi thực thi các truy vấn sẽ cực kì chậm chạp.Có một sự tương tác nghịch giữa hiệu năng và độ phức tạp của dữ liệu.Hiệu năng
có thể suy giảm đáng kể trong các hệ RDBMs nếu chúng ta lưu những dữ liệu cực kì phức tạp và đồ sộ như ở các mạng xã hội
2.7 Các loại NoSQL phổ biến
2.7.1 MongoDB [2][3]
Mongo là một cơ sở dữ liệu NoSQL nguồn mở, hiệu năng cao, có tính mở rộng cao.Được viết bằng C++ Dùng cách lưu trữ BSON (Json được biên dịch) với giấy phép AGPL.Thay vì lưu trữ dữ liệu theo các bảng như các cơ sở dữ liệu cổ điển.MongoDB lưu cấu trúc dữ liệu thành các văn bản dựa JSON với mô hình động (gọi đó là BSON), khiến cho việc tích hợp dữ liệu cho các ứng dụng trở nên dễ dàng và nhanh hơn.Với mục tiêu là kết hợp các điểm mạnh của mô hình key-values (nhanh mà tính mở rộng cao) với mô hình
dữ liệu quan hệ ( giàu chức năng)
Mục tiêu chính của Mongo là giữ lại các thuộc tính thân thiện của SQL.Do đó các câu truy vấn khá giống với SQL nên MongoDB khá thích hợp cho các lập trình viên đã quen với ngôn ngữ truy vấn SQL.MongoDB có một khối lượng tính năng lớn và hiệu năng cao.Với các loại dữ liệu phong phú, nhiều truy vấn và việc giảm thời gian phát triển trong việc mô hình hóa các đối tượng
MongoDB được sử dụng tốt nhất với nhu cầu cần truy vấn động, nếu bạn muốn định nghĩa chỉ mục mà không cần các hàm map/reduce.Đặc biệt nếu bạn cần tốc độ nhanh cho một cơ sở dữ liệu lớn vì MongoDB ngoài tốc độ đọc nhanh ra thì tốc độ ghi của nó rất nhanh
Các đặc điểm chính của mongoDB là:
Các truy vấn Ad hoc: Mongo hỗ trợ việc tìm theo trường, khoảng kết quả
tìm và tìm theo cú pháp.Các truy vấn có thể trả về các trường được qui định