- Máy chủ)
2.3.4 Giải pháp của google AppEngine
Google App Engine (gọi tắt là AppEngine, một số trường hợp được viết tắt là GAE) là giải pháp cho vấn đề điện toán đám mây. Ở đó, Google cung cấp sẵn một hệ thống máy chủ điện toán đám mây, và người lập trình sẽ viết ứng dụng của mình lên đó. Ứng dụng này sẽ chạy trên đám mây của Google.
Google App Engine là một nền tảng điện toán đám mây của Google để phát triển và lưu trữ ứng dụng web trong những trung tâm dữ liệu do Google quản lý (google-managed data centers). Bản beta được giới thiệu lần đầu tiên vào ngày 7 tháng 4 năm 2008.
GAE là 1 dịch vụ lưu trữ các ứng dụng web. Khi nói đến “ứng dụng web”, chúng ta muốn nói tới các ứng dụng hay dịch vụ được truy cập trên các trang web, thường là thông qua trình duyệt web: những trang web mua bán, mạng xã hội, … App Engine cũng có thể phục vụ các trang web truyền thống như xử lý văn bản hay hình ảnh nhưng được thiết kế dành cho thời gian thực.
Thực ra, GAE được thiết kế để lưu trữ những ứng dụng và phục vụ nhiều người dùng một cách đồng thời. Khi một ứng dụng có thể phục vụ nhiều người dùng một cách đồng thời mà không làm giảm hiệu suất, chúng ta gọi đó là sự co giãn . Những ứng dụng được viết cho App Engine sẽ được co giãn một cách tự động. Càng nhiều người sử dụng chương trình, App Engine sẽ tạo ra càng nhiều tài nguyên cho ứng dụng đó và quản lý chúng. Chính bản thân ứng dụng cũng không cần phải biết đến các tài nguyên mà nó đang sử dụng.
Không như những server cung cấp các dịch vụ lưu trữ thông thường hay các server có chức năng tự quản lý, với Google App Engine, chúng ta chỉ phải trả tiền cho những tài nguyên mà chúng ta sử dụng. Những tài nguyên này được đo bằng gigabyte và không có bất kì lệ phí hàng tháng nào hay lệ phí để chúng ta thay đổi diện mạo trang web. Hóa đơn thanh toán những
Số hóa bởi Trung tâm Học liệu http://www.lrc-tnu.edu.vn/
nguồn tài nguyên này bao gồm CPU chúng ta sử dụng, lưu trữ hàng tháng, băng thông vào ra, và một số các tài nguyên khác của dịch vụ App Engine. Sẽ có khoảng 500 MB lưu trữ miễn phí, một lượng tài nguyên miễn phí đủ để chạy những ứng dụng nhỏ với băng thông thấp. Google dự toán rằng với nguồn tài nguyên miễn phí, một ứng dụng có thể đạt tới 5 triệu lượt truy cập trong một tháng.
Kiến trúc hoạt động: Kiến trúc của App Engine khác với những server lưu trữ ứng dụng web thông thường. Ở phần lõi của nó, App Engine sẽ hạn chế những truy cập từ ứng dụng của chúng ta đến cơ sở hạ tầng vật lý, ngăn cản chúng ta từ việc mở các socket, chạy các tiến trình ngầm, hay các cách đi khác bằng cổng sau để giúp chương trình của ta có quyền trên môi trường này. App Engine được thiết kế để giải quyết mối quan tâm của chúng ta về sự mở rộng và độ tin cậy. Nó được xây dựng dựa trên khái niệm có thể mở rộng theo chiều ngang, nghĩa là thay vì ứng dụng của chúng ta sẽ được chạy trên một phần cứng mạnh mẽ, thì nó có thể chạy trên nhiều phần cứng yếu hơn. App Engine chạy như một thực thể cô lập trong môi trường gồm nhiều thành phần. Chúng ta thấy, App Engine chia sẻ những nguồn tài nguyên giữa các ứng dụng nhưng cô lập về dữ liệu và bảo mật giữa những thành phần với nhau. Ứng dụng của chúng ta có thể sử dụng một số các dịch vụ của Google, như là URLFetch. Bởi vì chúng ta không thể mở cổng một cách trực tiếp trong ứng dụng của mình, nên chúng ta phải lệ thuộc vào dịch vụ này, ví dụ: yêu cầu Google mở cổng và thực thi ứng dụng của mình.
Như vậy, trong GAE, tùy vào ứng dụng viết theo ngôn ngữ nào, nó sẽ được chạy trên môi trường Java hay Python tương ứng. Song song đó, chúng ta sẽ được cung cấp sử dụng miễn phí các dịch vụ của google như URL Fetch, Mail, Memcache, … và được lưu trữ trên cơ sở dữ liệu hướng đối tượng datastore. Khi yêu cầu được gửi lên từ phía người dùng, GAE sẽ chuyển yêu
Số hóa bởi Trung tâm Học liệu http://www.lrc-tnu.edu.vn/
35
cầu đó cho ứng dụng của chúng ta. Tùy theo việc xử lý chúng mà ta cấu hình và sử dụng các ứng dụng thích hợp của GAE.
Google App Engine cung cấp môi trường phát triển đầy đủ tính năng giống như Google App Engine được cài đặt trên tính máy tính của người dùng. Ứng dụng chủ yếu chạy trên hai môi trường là Java và Python.
Môi trường thực thi (runtime environment): Một ứng dụng App Engine đáp ứng các yêu cầu web. Một yêu cầu web sẽ bắt đầu khi có một người dùng hay điển hình là các trình duyệt web của người dùng gửi một yêu cầu truy cập vào ứng dụng thông qua giao thức HTTP. Khi App Engine nhận được yêu cầu, nó sẽ xác định ứng dụng dựa vào tên miền, hoặc tên miền con của <tên bạn>.appspot.com (cung cấp miễn phí mỗi ứng dụng) hoặc là một tên miền riêng của chúng ta đã được đăng kí và thiết lập với Google Apps. App Engine lựa chọn một máy chủ từ nhiều máy chủ để xử lý các yêu cầu đó. Sau đó, App Engine sẽ gửi các yêu cầu đã nhận được từ người dùng đến ứng dụng phù hợp để xử lý, sau khi đã xử lý xong các ứng dụng này sẽ gửi dữ liệu trả về cho App Engine, App Engine sẽ nhận dữ liệu phản hồi từ các ứng dụng và trả về cho người dùng thông qua trình duyệt web.
Google App Engine cung cấp hai môi trường thực thi tốt cho các ứng dụng. Đó là Java và Python. Môi trường chúng ta chọn sẽ phụ thuộc vào ngôn ngữ và những công nghệ liên quan khi chúng ta dùng để phát triển ứng dụng.
Cả hai môi trường Java và Python đều sử dụng chung một mô hình: một yêu cầu gửi đến ứng dụng trên server, ứng dụng được kích hoạt (nếu cần thiết), gọi bộ phận xử lý yêu cầu và trả về kết quả cho client. Mỗi môi trường sử dụng bộ tiền xử lý cho riêng mình.
- Kiến trúc lƣu trữ dữ liệu trên ĐTĐM
Môi trường Google App Engine cung cấp nhiều lựa chọn để lưu trữ dữ liệu cho các ứng dụng:
Số hóa bởi Trung tâm Học liệu http://www.lrc-tnu.edu.vn/
App Engine Datastore (Kho dữ liệu): đối tượng datastore không sơ đồ với các chức năng như tự động cache, máy truy vẫn dữ liệu tinh vi (query engine), và những giao dịch nguyên tử (atomic transactions). Google Cloud SQL: Một cơ sở dữ liệu SQL quan hệ cho ứng dụng App Engine, tương tự như cơ sở dữ liệu MySQL.
Google Cloud Store: Một dịch vụ lưu trữ cho các đối tượng và các files với dung lượng lên tời hàng Terabytes. Các ứng dụng App Engine truy cập đến dịch vụ này thông qua thư viện client của Google Cloud Store.
Trong luận văn này sẽ sử dụng Datastore để lưu trữ dữ liệu cho ứng dụng của doanh nghiệp vừa và nhỏ. Trước hết chúng ta xem kiến trúc lưu trữ dữ liệu của Google App Engine.
Trên Hình 2.6 là sơ đồ triển khai thực tế của ứng dụng App Engine. Người dùng tương tác với các ứng dụng thông qua Browser. Google‟s Load Balancer sẽ điều phối request của người dùng đến các ứng dụng App Engine tương ứng (các Node tương ứng) trong các Google Cluster. Các kho dữ liệu (Datastore) tương tự cũng được chia ra thành nhiều cụm trên nhiều Datastore Cluster khác nhau. Các Node ở các Google Cluster tương tác với Datastore thông qua cơ chế gọi các thủ tục từ xa của Google (Google‟s RPC Mechanism).
Trên Hình 2.7 là sơ đồ các thành phần của một Node trong Datastore Cluster. Mỗi Node này cung cấp các APIs để làm việc với cơ sở dữ liệu thực sự được lưu trong BigTable – Cơ sở dữ liệu không quan hệ (NoSQL) của Google, cho phép lưu trữ dữ liệu cực lớn (BigData) với tốc độ của các thao tác đọc-ghi nhanh.
Số hóa bởi Trung tâm Học liệu http://www.lrc-tnu.edu.vn/
37
Hình 2.6. Sơ đồ triển khai thực tế App Engine
Số hóa bởi Trung tâm Học liệu http://www.lrc-tnu.edu.vn/
- Datastore API
Trong mục này, chúng ta sẽ điểm qua về datastore của Google App Engine. + Entity & Properties
Một ứng dụng App Engine có thể chứa dữ liệu trong một hoặc nhiều thực thể (entity). Mỗi thực thể có hoặc nhiều thuôc tính (properties), mỗi thuộc tính đều có tên và giá trị. Mỗi thực thể đều được phân loại để tiện cho việc truy vấn.
Đầu tiên, chúng ta thấy thực thể có thể gần giống với các hàng (row) của một bảng (table) trong cơ sở dữ liệu quan hệ. Và mỗi thuộc tính có thể giống với một cột (column). Tuy nhiên, đối với các thực thể cùng loại với nhau có thể có các thuộc tính khác nhau. Điểm khác nhau giữa thực thể và các hàng là thực thể có thể có nhiều giá trị cho một thuộc tính đơn lẻ.
Mỗi thực thể có một khóa riêng (key) để phân biệt, và được cung cấp bởi ứng dụng hoặc App Engine. Khác với cơ sở dữ liệu quan hệ, khóa của thực thể không phải là thuộc tính, nó tồn tại độc lập với thực thể. Khóa của thực thể không thể thay đổi khi nó được tạo ra.
Đối với datastore, ta nên hiểu nó chỉ là một bảng rất lớn. Đó là lý do mà nó có tên là BigTable. Vì thế, khóa là để phân biệt thực thể này với tất cả các thực thể khác trong cùng cái bảng to lớn ấy. Khóa có 2 dạng:
Một là dạng khóa mà chúng ta chỉ định tên để có thể sử dụng sau này. Hai là nếu ta không chỉ định tên cho khóa, hệ thống sẽ phát sinh một định danh (ID) cho thực thể của chúng ta.
Vì thế, một thực thể hoặc là có tên khóa hoặc là ID của khóa. Chú ý là việc gán tên khóa chỉ xảy ra khi thực thể được khởi tạo và giá trị đó không thể thay đổi được.
Số hóa bởi Trung tâm Học liệu http://www.lrc-tnu.edu.vn/
39
Thuộc tính tĩnh (fixed property): với thuộc tính tĩnh, ta có thể hình dung nó như là các cột trong cơ sở dữ liệu quan hệ, có giá trị và cùng kiểu dữ liệu.
Thuộc tính động (dynamic property): với thuộc tính động, số lượng thuộc tính lại được thay đổi tùy vào mục đích của chúng ta. Vì thế, mặc dù là một thực thể, nhưng 2 thể hiện có thể có số lượng thuộc tính động khác nhau. Mỗi thuộc tính đều có kiểu dữ liệu riêng của nó.
+ Queries & Index
Các kiểu dữ liệu trên datastore đã được đánh chỉ mục (index) một cách tự động. Tuy nhiên, chúng ta phải khai báo chỉ mục cho những thuộc tính cần sử dụng trong câu truy vấn (query), và là datastore yêu cầu bắt buộc điều đó.
Một truy vấn trên datastore sẽ trả về không hoặc nhiều thực thể cùng loại với nhau. Nó có thể trả về các khóa của thực thể. Câu truy vấn có thể dựa vào các giá trị thuộc tính của thực thể và được sắp xếp theo giá trị của thuộc tính. Câu truy vấn cũng có thể làm việc với các khóa của thực thể.
Với App Engine, mỗi câu truy vấn sẽ có một chỉ mục (index) trong datastore. Khi ứng dụng cần thực hiện một truy vấn, datastore sẽ tìm chỉ mục của truy vấn đó. Khi tạo mới một thực thể và cập nhật cái cũ, datastore sẽ cập nhật lại chỉ mục. Điều này giúp cho câu truy vấn được nhanh hơn.
+ Transaction
Khi chúng ta sử dụng nhiều câu truy vấn cho cùng một mục đích và muốn đảm bảo: hoặc tất các các truy vấn thực hiện thành công, hoặc nếu một trong các truy vấn đó thất bại, sẽ không có truy vấn nào được phép chạy. Khi đó, ta cần một phiên giao dịch (transaction) để đảm bảo yêu cầu như thế.
Mỗi phiên giao dịch chỉ có 2 trạng thái là thành công hoặc thất bại. Tuy nhiên, các thực thể sử dụng trong một transaction phải cùng một nhóm. Nhờ nhóm thực thể, App Engine sẽ biết được các thực thể sẽ phân tán như thế nào qua các server, vì thế nó có thể khẳng định chắc chắn là phiên giao dịch thành công hay thất bại. App Engine cũng hỗ trợ phiên giao dịch nội bộ (local transaction).
Số hóa bởi Trung tâm Học liệu http://www.lrc-tnu.edu.vn/
Việc cấu hình các thực thể thuộc cùng một nhóm được thực hiện lúc khởi tạo thực thể và sẽ không thể thay đổi về sau.
Khi khởi tạo thực thể, nếu thực thể đó không là con của bất kỳ thực thể nào thì nó là thực thể gốc (root entity). Và nó sẽ nằm trong nhóm của chính mình. Bất kỳ thực thể nào khác muốn nằm trong nhóm này đều phải chỉ định thực thể này là cha, hoặc các bất kỳ thực thể nào khác nằm trong nhóm này là cha của mình.
+ Services
App Engine cung cấp nhiều dịch vụ cho phép bạn dễ dàng quản lý ứng dụng: URL Fletch: cho phép ứng dụng truy cập tài nguyên trên internet.
Mail: cho phép ứng dụng thưc hiện gửi thư điện thử thông qua các dịch mail của Google.
Memcache: là dịch vụ cho phép ứng dụng hoạt động có hiệu suất cao với vùng nhớ đệm trong nhiều trường hợp.
Image Manipulation: dịch vụ cho phép ứng dụng của bạn thao tác trên hình ảnh: thay đổi size, cắt, xoay, lật ảnh JPEG và PNG.
+ Các cách tạo một Entity sử dụng API
Như đã nói ở phần trên, entity là đối tượng chứa dữ liệu trong datastore. Sau đây là cách tạo 1 entity:
import com.google.appengine.api.datastore.Entity;
Entity employee = new Entity("Employee"); employee.setProperty("firstName", "Tien"); employee.setProperty("lastName", "Vo");
employee.setProperty("hireDate", new Date()); employee.setProperty("attendedHrTraining", true);
Ở đây entity có 4 thuộc tính là firstName, lastName, hireDate và attendedHrTraining. Loại của entity là Employee và entity của chúng ta được hệ thống tự động đánh số id ngẫu nhiên vì chúng ta chưa hề chỉ định tên cho khóa dành cho entity này. Với việc đặt tên cho khóa, chúng ta làm như sau:
Số hóa bởi Trung tâm Học liệu http://www.lrc-tnu.edu.vn/
41
Entity employee = new Entity("Employee", "demoKey");
Entity chúng ta vừa tạo đã có tên cho khóa là “demoKey” và đây là entity gốc vì nó không có entity cha. Để tạo 1 entity loại Address có cha là entity loại Employee, chúng ta làm như sau:
Entity address = new Entity("Address", employee.getKey());
Như vậy lúc này Address và Employee cùng chung 1 nhóm entity mang tên Employee. Việc tạo ra các entity chung nhóm để có thể sử dụng trong transaction.
Các entity chúng ta vừa mới tạo sử dụng API của datastore, và đó là các entity mang các thuộc tính động. Điều dễ hiểu là chúng ta có thể thay đổi kiểu dữ liệu của 1 thuộc tính hay thêm bớt số lượng thuộc tính của nhiều thể hiện trong cùng một loại:
Entity employee = new Entity("Employee", "demoKey"); employee.setProperty("firstName", "Tien");
employee.setProperty("lastName", "Vo");
employee.setProperty("hireDate", new Date()); employee.setProperty("attendedHrTraining", true); Entity employee2 = new Entity("Employee");
employee2.setProperty("firstName", "Tien"); employee2.setProperty("lastName", "Vo");
employee2.setProperty("attendedHrTraining", new Date());
Tuy nhiên, việc tạo entity có thuộc tính động mang lại những lợi ích như ta hoàn toàn thoải mái định nghĩa kiểu dữ liệu, hoặc có thể thay đổi số lượng thuộc tính. Thế nhưng bạn phải tự định nghĩa ra cơ chế để có thể không nhầm lẫn giữa các kiểu dữ liệu của các thuộc tính động do bạn tạo ra. Bạn có thể biết thuộc tính x của thể hiện A kiểu integer nhưng chưa chắc thuộc tính x của thể hiện B là kiểu integer mặc dù A và B là 2 thể hiện của cùng 1 loại. Datastore không có cơ chế kiểm tra dùm cho bạn.
Nếu bạn cần một entity có những thuộc tính tĩnh, các thuộc tính này bắt buộc phải cùng kiểu dữ liệu trên các thể hiện, thì chúng ta có 2 cách. App
Số hóa bởi Trung tâm Học liệu http://www.lrc-tnu.edu.vn/
Engine cài đặt 2 giao diện chuẩn đó là JDO và JPA. Với việc sử dụng 1 trong 2 giao diện trên, bạn có thể tạo ra được entity với thuộc tính cố định. Để tạo ra entity loại A, bạn cần định nghĩa 1 class A và khai báo các thuộc tính kèm theo kiểu dữ liệu mà bạn muốn entity của bạn có. Tuy nhiên để sử dụng JDO hoặc JPA, chúng ta cần phải cấu hình để App Engine nhận biết chúng. Sau đây là cách cấu hình JDO:
Để JDO có thể truy cập datastore, chúng ta cần phải làm những điều