MongoDB
 sql >> Cơ Sở Dữ Liệu >  >> NoSQL >> MongoDB

Hướng dẫn PyMongo:Kiểm tra chuyển đổi dự phòng MongoDB trong ứng dụng Python của bạn

Python là ngôn ngữ lập trình mạnh mẽ và linh hoạt được hàng triệu nhà phát triển trên khắp thế giới sử dụng để xây dựng các ứng dụng của họ. Không có gì ngạc nhiên khi các nhà phát triển Python thường tận dụng lưu trữ MongoDB, cơ sở dữ liệu NoSQL phổ biến nhất, để triển khai do tính chất linh hoạt và thiếu các yêu cầu về lược đồ.

Vậy cách tốt nhất để sử dụng MongoDB với Python là gì? PyMongo là một bản phân phối Python chứa các công cụ để làm việc với MongoDB và trình điều khiển Python MongoDB được đề xuất. Đây là một trình điều khiển khá thuần thục hỗ trợ hầu hết các hoạt động phổ biến với cơ sở dữ liệu.

Khi triển khai trong phiên bản sản xuất, bạn nên thiết lập trong cấu hình bộ bản sao MongoDB để dữ liệu của bạn được phân phối theo địa lý để có tính khả dụng cao. Chúng tôi cũng khuyến nghị rằng các kết nối SSL được kích hoạt để mã hóa lưu lượng truy cập cơ sở dữ liệu máy khách. Chúng tôi thường tiến hành kiểm tra các đặc tính chuyển đổi dự phòng của các trình điều khiển MongoDB khác nhau để đủ điều kiện cho các trường hợp sử dụng sản xuất hoặc khi khách hàng yêu cầu chúng tôi tư vấn. Trong bài đăng này, chúng tôi hướng dẫn bạn cách kết nối với tập hợp bản sao MongoDB hỗ trợ SSL được định cấu hình với chứng chỉ tự ký bằng PyMongo và cách kiểm tra hành vi chuyển đổi dự phòng MongoDB trong mã của bạn.

Kết nối với MongoDB SSL bằng chứng chỉ tự ký

Bước đầu tiên là đảm bảo rằng bạn đã cài đặt đúng phiên bản PyMongo và các phần phụ thuộc của nó. Hướng dẫn này giúp bạn phân loại các phần phụ thuộc và bạn có thể tìm thấy ma trận khả năng tương thích của trình điều khiển tại đây.

mongo_client.MongoClient các tham số mà chúng tôi quan tâm là ssl ss_ca_cert . Để kết nối với điểm cuối MongoDB hỗ trợ SSL sử dụng chứng chỉ tự ký, ssl phải được đặt thành True ss_ca_cert phải trỏ đến tệp chứng chỉ CA.

Nếu bạn là khách hàng của ScaleGrid, bạn có thể tải xuống tệp chứng chỉ CA cho các cụm MongoDB của mình từ bảng điều khiển ScaleGrid như được hiển thị ở đây:

Vì vậy, đoạn mã kết nối sẽ giống như sau:

>>> import pymongo
>>> MONGO_URI = 'mongodb://rwuser:@SG-example-0.servers.mongodirector.com:27017,SG-example-1.servers.mongodirector.com:27017,SG-example-2.servers.mongodirector.com:27017/admin?replicaSet=RS-example&ssl=true'
>>> client = pymongo.MongoClient(MONGO_URI, ssl = True, ssl_ca_certs = '')
>>> print("Databases - " + str(client.list_database_names()))
Databases - ['admin', 'local', 'test']
>>> client.close()
>>>

Nếu bạn đang sử dụng chứng chỉ tự ký của chính mình trong đó xác minh tên máy chủ có thể không thành công, bạn cũng sẽ phải đặt ssl_match_hostname tham số thành False . Giống như tài liệu trình điều khiển đã nói, điều này không được khuyến khích vì nó làm cho kết nối dễ bị tấn công kẻ trung gian.

Kiểm tra hành vi chuyển đổi dự phòng

Với việc triển khai MongoDB, chuyển dự phòng không được coi là sự kiện lớn như với các hệ thống quản lý cơ sở dữ liệu truyền thống. Mặc dù hầu hết các trình điều khiển MongoDB cố gắng tóm tắt sự kiện này, nhưng các nhà phát triển nên hiểu và thiết kế ứng dụng của họ cho hành vi đó, vì các ứng dụng sẽ có lỗi mạng tạm thời và thử lại trước khi tô màu lỗi.

Bạn có thể kiểm tra khả năng phục hồi của các ứng dụng bằng cách tạo ra các chuyển đổi dự phòng trong khi khối lượng công việc của bạn đang chạy. Cách dễ nhất để tạo chuyển đổi dự phòng là chạy lệnh rs.stepDown ():

RS-example-0:PRIMARY> rs.stepDown()
2019-04-18T19:44:42.257+0530 E QUERY [thread1] Error: error doing query: failed: network error while attempting to run command 'replSetStepDown' on host 'SG-example-1.servers.mongodirector.com:27017' :
DB.prototype.runCommand@src/mongo/shell/db.js:168:1
DB.prototype.adminCommand@src/mongo/shell/db.js:185:1
rs.stepDown@src/mongo/shell/utils.js:1305:12
@(shell):1:1
2019-04-18T19:44:42.261+0530 I NETWORK [thread1] trying reconnect to SG-example-1.servers.mongodirector.com:27017 (X.X.X.X) failed
2019-04-18T19:44:43.267+0530 I NETWORK [thread1] reconnect SG-example-1.servers.mongodirector.com:27017 (X.X.X.X) ok
RS-example-0:SECONDARY>

Một trong những cách tôi thích để kiểm tra hành vi của người lái xe là viết một ứng dụng viết ‘vĩnh viễn’ đơn giản. Đây sẽ là mã đơn giản tiếp tục ghi vào cơ sở dữ liệu trừ khi bị gián đoạn bởi người dùng và sẽ in tất cả các ngoại lệ mà nó gặp phải để giúp chúng tôi hiểu trình điều khiển và hành vi cơ sở dữ liệu. Tôi cũng theo dõi dữ liệu mà nó ghi để đảm bảo rằng không có mất mát dữ liệu không được báo cáo nào trong quá trình kiểm tra. Dưới đây là phần có liên quan của mã kiểm tra mà chúng tôi sẽ sử dụng để kiểm tra hành vi chuyển đổi dự phòng MongoDB của mình:

import logging
import traceback
...
import pymongo
...
logger = logging.getLogger("test")

MONGO_URI = 'mongodb://rwuser:@SG-example-0.servers.mongodirector.com:48273,SG-example-1.servers.mongodirector.com:27017,SG-example-2.servers.mongodirector.com:27017/admin?replicaSet=RS-example-0&ssl=true'

try:
    logger.info("Attempting to connect...")
    client = pymongo.MongoClient(MONGO_URI, ssl = True, ssl_ca_certs = 'path-to-cacert.pem')
    db = client['test']
    collection = db['test']
    i = 0
    while True:
        try:
            text = ''.join(random.choices(string.ascii_uppercase + string.digits, k = 3))
            doc = { "idx": i, "date" : datetime.utcnow(), "text" : text}
            i += 1
            id = collection.insert_one(doc).inserted_id
            logger.info("Record inserted - id: " + str(id))
            sleep(3)
        except pymongo.errors.ConnectionFailure as e:
            logger.error("ConnectionFailure seen: " + str(e))
            traceback.print_exc(file = sys.stdout)
            logger.info("Retrying...")

    logger.info("Done...")
except Exception as e:
    logger.error("Exception seen: " + str(e))
    traceback.print_exc(file = sys.stdout)
finally:
    client.close()

Loại mục nhập mà điều này viết trông giống như:

RS-example-0:PRIMARY> db.test.find()
{ "_id" : ObjectId("5cb6d6269ece140f18d05438"), "idx" : 0, "date" : ISODate("2019-04-17T07:30:46.533Z"), "text" : "400" }
{ "_id" : ObjectId("5cb6d6299ece140f18d05439"), "idx" : 1, "date" : ISODate("2019-04-17T07:30:49.755Z"), "text" : "X63" }
{ "_id" : ObjectId("5cb6d62c9ece140f18d0543a"), "idx" : 2, "date" : ISODate("2019-04-17T07:30:52.976Z"), "text" : "5BX" }
{ "_id" : ObjectId("5cb6d6329ece140f18d0543c"), "idx" : 4, "date" : ISODate("2019-04-17T07:30:58.001Z"), "text" : "TGQ" }
{ "_id" : ObjectId("5cb6d63f9ece140f18d0543d"), "idx" : 5, "date" : ISODate("2019-04-17T07:31:11.417Z"), "text" : "ZWA" }
{ "_id" : ObjectId("5cb6d6429ece140f18d0543e"), "idx" : 6, "date" : ISODate("2019-04-17T07:31:14.654Z"), "text" : "WSR" }
..

Xử lý ngoại lệ ConnectionFailure

Lưu ý rằng chúng tôi bắt được ngoại lệ ConnectionFailure để giải quyết tất cả các vấn đề liên quan đến mạng mà chúng tôi có thể gặp phải do chuyển đổi dự phòng - chúng tôi in ngoại lệ và tiếp tục cố gắng ghi vào cơ sở dữ liệu. Tài liệu trình điều khiển khuyến nghị rằng:

Nếu một hoạt động không thành công do lỗi mạng, ConnectionFailure sẽ được nâng lên và máy khách kết nối lại trong nền. Mã ứng dụng phải xử lý ngoại lệ này (nhận biết rằng thao tác không thành công) và sau đó tiếp tục thực thi.

Hãy chạy phần này và thực hiện chuyển đổi dự phòng cơ sở dữ liệu trong khi thực thi. Đây là những gì sẽ xảy ra:

04/17/2019 12:49:17 PM INFO Attempting to connect...
04/17/2019 12:49:20 PM INFO Record inserted - id: 5cb6d3789ece145a2408cbc7
04/17/2019 12:49:23 PM INFO Record inserted - id: 5cb6d37b9ece145a2408cbc8
04/17/2019 12:49:27 PM INFO Record inserted - id: 5cb6d37e9ece145a2408cbc9
04/17/2019 12:49:30 PM ERROR PyMongoError seen: connection closed
Traceback (most recent call last):
    id = collection.insert_one(doc).inserted_id
  File "C:\Users\Random\AppData\Local\Programs\Python\Python36-32\lib\site-packages\pymongo\collection.py", line 693, in insert_one
    session=session),
...
  File "C:\Users\Random\AppData\Local\Programs\Python\Python36-32\lib\site-packages\pymongo\network.py", line 173, in receive_message
    _receive_data_on_socket(sock, 16))
  File "C:\Users\Random\AppData\Local\Programs\Python\Python36-32\lib\site-packages\pymongo\network.py", line 238, in _receive_data_on_socket
    raise AutoReconnect("connection closed")
pymongo.errors.AutoReconnect: connection closed
04/17/2019 12:49:30 PM INFO Retrying...
04/17/2019 12:49:42 PM INFO Record inserted - id: 5cb6d3829ece145a2408cbcb
04/17/2019 12:49:45 PM INFO Record inserted - id: 5cb6d3919ece145a2408cbcc
04/17/2019 12:49:49 PM INFO Record inserted - id: 5cb6d3949ece145a2408cbcd
04/17/2019 12:49:52 PM INFO Record inserted - id: 5cb6d3989ece145a2408cbce

Lưu ý rằng trình điều khiển mất khoảng 12 giây để hiểu cấu trúc liên kết mới, kết nối với cấu trúc chính mới và tiếp tục viết. Ngoại lệ được nêu ra là lỗi . Tự động kết nối là một lớp con của ConnectionFailure .

PyMongo Hướng dẫn:Thử nghiệm chuyển đổi dự phòng MongoDB trong ứng dụng Python của bạn Nhấp để Tweet

Bạn có thể thực hiện thêm một vài lần chạy nữa để xem có những ngoại lệ nào khác. Ví dụ:đây là một dấu vết ngoại lệ khác mà tôi gặp phải:

    id = collection.insert_one(doc).inserted_id
  File "C:\Users\Random\AppData\Local\Programs\Python\Python36-32\lib\site-packages\pymongo\collection.py", line 693, in insert_one
    session=session),
...
  File "C:\Users\Randome\AppData\Local\Programs\Python\Python36-32\lib\site-packages\pymongo\network.py", line 150, in command
    parse_write_concern_error=parse_write_concern_error)
  File "C:\Users\Random\AppData\Local\Programs\Python\Python36-32\lib\site-packages\pymongo\helpers.py", line 132, in _check_command_response
    raise NotMasterError(errmsg, response)
pymongo.errors.NotMasterError: not master

Ngoại lệ này cũng là một lớp con của ConnectionFailure.

Tham số

‘retryWrites’

Một khu vực khác để kiểm tra hành vi chuyển đổi dự phòng MongoDB sẽ là xem các biến thể tham số khác ảnh hưởng như thế nào đến kết quả. Một tham số có liên quan là ‘ retryWrites ‘:

retryWrites:(boolean) Liệu các hoạt động ghi được hỗ trợ có được thực thi trong MongoClient này hay không sẽ được thử lại một lần sau khi có lỗi mạng trên MongoDB 3.6+. Mặc định là Sai.

Hãy xem thông số này hoạt động như thế nào với chuyển đổi dự phòng. Thay đổi duy nhất được thực hiện đối với mã là:

client = pymongo.MongoClient(MONGO_URI, ssl = True, ssl_ca_certs = 'path-to-cacert.pem', retryWrites = True)

Hãy chạy nó ngay bây giờ và sau đó thực hiện chuyển đổi dự phòng hệ thống cơ sở dữ liệu:

04/18/2019 08:49:30 PM INFO Attempting to connect...
04/18/2019 08:49:35 PM INFO Record inserted - id: 5cb895869ece146554010c77
04/18/2019 08:49:38 PM INFO Record inserted - id: 5cb8958a9ece146554010c78
04/18/2019 08:49:41 PM INFO Record inserted - id: 5cb8958d9ece146554010c79
04/18/2019 08:49:44 PM INFO Record inserted - id: 5cb895909ece146554010c7a
04/18/2019 08:49:48 PM INFO Record inserted - id: 5cb895939ece146554010c7b <<< Failover around this time
04/18/2019 08:50:04 PM INFO Record inserted - id: 5cb895979ece146554010c7c
04/18/2019 08:50:07 PM INFO Record inserted - id: 5cb895a79ece146554010c7d
04/18/2019 08:50:10 PM INFO Record inserted - id: 5cb895aa9ece146554010c7e
04/18/2019 08:50:14 PM INFO Record inserted - id: 5cb895ad9ece146554010c7f
...

Lưu ý cách chèn sau khi chuyển đổi dự phòng mất khoảng 12 giây, nhưng diễn ra thành công khi ghi lại tham số đảm bảo việc ghi không thành công được thử lại. Hãy nhớ rằng việc đặt thông số này không giúp bạn xử lý ConnectionFailure ngoại lệ - bạn cần phải lo lắng về các lần đọc và các hoạt động khác mà hành vi của chúng không bị ảnh hưởng bởi tham số này. Nó cũng không giải quyết được hoàn toàn vấn đề, ngay cả đối với các hoạt động được hỗ trợ - đôi khi quá trình chuyển dự phòng có thể mất nhiều thời gian hơn để hoàn thành và ghi lại một mình sẽ không đủ.

Định cấu hình giá trị thời gian chờ của mạng

rs.stepDown () tạo ra một sự chuyển đổi dự phòng khá nhanh chóng, vì tập hợp bản sao chính được cấu trúc để trở thành phụ và những người thứ hai tổ chức một cuộc bầu cử để xác định sơ cấp mới. Trong triển khai sản xuất, tải mạng, phân vùng và các vấn đề khác làm chậm việc phát hiện tình trạng không khả dụng của máy chủ chính, do đó, kéo dài thời gian chuyển đổi dự phòng của bạn. Bạn cũng sẽ thường gặp các lỗi PyMongo như error.ServerSelectionTimeoutError , error.NetworkTimeout, vv trong các sự cố mạng và chuyển đổi dự phòng.

Nếu điều này xảy ra rất thường xuyên, bạn phải tìm cách điều chỉnh thông số thời gian chờ. MongoClient có liên quan tham số thời gian chờ là serverSelectionTimeoutMS , connectTimeoutMS, socketTimeoutMS . Trong số này, chọn một giá trị lớn hơn cho serverSelectionTimeoutMS thường giúp xử lý các lỗi trong quá trình chuyển đổi dự phòng:

serverSelectionTimeoutMS:(số nguyên) Kiểm soát thời gian (tính bằng mili giây) trình điều khiển sẽ đợi để tìm một máy chủ khả dụng, thích hợp để thực hiện hoạt động cơ sở dữ liệu; trong khi chờ đợi, nhiều hoạt động giám sát máy chủ có thể được thực hiện, mỗi hoạt động được kiểm soát bởi connectTimeoutMS. Mặc định là 30000 (30 giây).

Bạn đã sẵn sàng sử dụng MongoDB trong ứng dụng Python của mình chưa? Hãy xem bài viết Bắt đầu với Python và MongoDB của chúng tôi để biết cách bạn có thể thiết lập và chạy chỉ trong 5 bước đơn giản. ScaleGrid là nhà cung cấp MongoDB DBaaS duy nhất cung cấp cho bạn quyền truy cập SSH đầy đủ vào các phiên bản của bạn để bạn có thể chạy máy chủ Python của mình trên cùng một máy với máy chủ MongoDB của bạn. Tự động hóa việc triển khai đám mây MongoDB của bạn trên AWS, Azure hoặc DigitalOcean với các máy chủ chuyên dụng, tính khả dụng cao và khả năng phục hồi sau thảm họa để bạn có thể tập trung phát triển ứng dụng Python của mình.


  1. Redis
  2.   
  3. MongoDB
  4.   
  5. Memcached
  6.   
  7. HBase
  8.   
  9. CouchDB
  1. MongoParseError:các tùy chọn useCreateIndex, useFindAndModify không được hỗ trợ

  2. Tách chuỗi thành một mảng các chuỗi con hoặc ký tự trong MongoDB

  3. Nhà điều hành đường ống tổng hợp MongoDB $ type

  4. Quy trình tổng hợp Mongodb cách hạn chế đẩy nhóm

  5. Mongoose:Lược đồ vs Mô hình?