чтение репликации (+ pymongo) от ведомого, когда мастер не работает - PullRequest
3 голосов
/ 26 февраля 2012

Похоже, что при использовании pymongo соединение всегда будет пытаться прочитать из PRIMARY, а когда оно не работает, возникает ошибка сокета до завершения нового процесса выборов.

Учитываятот факт, что одна из целей replicSet - это сбалансировать нагрузку чтения, это кажется серьезным недостатком, если я не пропускаю здесь ключевую концепцию.

Я предоставил slave_ok, хотя пока нет первичнойдоступны, нет чтения, не говоря уже о записи доступны также.

Я запустил 3 экземпляра mongod на портах 8910,8911 и 8912 и снял их один за другим, когда оставался последний, не былоспособ чтения из него, даже если вы монго (cli) дайте читать.

Используемые версии:

mongodb: 2.0.2
pymongo: 2.1.1

Pymongo Консольный вывод

>>> collection = Connection("localhost:8910, localhost:8911, localhost:8912", slave_okay=True).testdb['TEST']
>>> len(list(collection.find()))
0
>>> collection.insert({"a": 1})
ObjectId('4f4a491bb9efb72ec8000045')
>>> len(list(collection.find()))
1

убирает 1 из 3 экземпляров (основной), а затем ...

>>> len(list(collection.find()))
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/usr/local/lib/python2.7/dist-packages/pymongo-2.1.1-py2.7-linux-x86_64.egg/pymongo/cursor.py", line 703, in next
    if len(self.__data) or self._refresh():
  File "/usr/local/lib/python2.7/dist-packages/pymongo-2.1.1-py2.7-linux-x86_64.egg/pymongo/cursor.py", line 666, in _refresh
    self.__uuid_subtype))
  File "/usr/local/lib/python2.7/dist-packages/pymongo-2.1.1-py2.7-linux-x86_64.egg/pymongo/cursor.py", line 616, in __send_message
    **kwargs)
  File "/usr/local/lib/python2.7/dist-packages/pymongo-2.1.1-py2.7-linux-x86_64.egg/pymongo/connection.py", line 880, in _send_message_with_response
    sock = self.__socket()
  File "/usr/local/lib/python2.7/dist-packages/pymongo-2.1.1-py2.7-linux-x86_64.egg/pymongo/connection.py", line 686, in __socket
    sock, from_pool = self.__pool.get_socket(host, port)
  File "/usr/local/lib/python2.7/dist-packages/pymongo-2.1.1-py2.7-linux-x86_64.egg/pymongo/connection.py", line 165, in get_socket
    self.sock = (pid, self.connect(host, port))
  File "/usr/local/lib/python2.7/dist-packages/pymongo-2.1.1-py2.7-linux-x86_64.egg/pymongo/connection.py", line 127, in connect
    s.connect((host, port))
  File "/usr/lib/python2.7/socket.py", line 224, in meth
    return getattr(self._sock,name)(*args)
socket.error: [Errno 111] Connection refused
>>> 

был избран новый первичный,затем ...

>>> len(list(collection.find()))
1

убивая второй инстансce из 3, а затем ...

>>> collection.insert({"c": 3})
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/usr/local/lib/python2.7/dist-packages/pymongo-2.1.1-py2.7-linux-x86_64.egg/pymongo/collection.py", line 312, in insert
    continue_on_error, self.__uuid_subtype), safe)
  File "/usr/local/lib/python2.7/dist-packages/pymongo-2.1.1-py2.7-linux-x86_64.egg/pymongo/connection.py", line 811, in _send_message
    sock = self.__socket()
  File "/usr/local/lib/python2.7/dist-packages/pymongo-2.1.1-py2.7-linux-x86_64.egg/pymongo/connection.py", line 674, in __socket
    host, port = self.__find_node()
  File "/usr/local/lib/python2.7/dist-packages/pymongo-2.1.1-py2.7-linux-x86_64.egg/pymongo/connection.py", line 659, in __find_node
    raise AutoReconnect(', '.join(errors))
pymongo.errors.AutoReconnect: could not connect to  localhost:8911: [Errno -5] No address associated with hostname, could not connect to localhost:8911: [Errno 111] Connection refused, could not connect to localhost:8912: [Errno 111] Connection refused, could not connect to  localhost:8912: [Errno -5] No address associated with hostname, localhost:8910 is not primary or master
>>> 
>>> 
>>> collection.insert({"c": 3})
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/usr/local/lib/python2.7/dist-packages/pymongo-2.1.1-py2.7-linux-x86_64.egg/pymongo/collection.py", line 312, in insert
    continue_on_error, self.__uuid_subtype), safe)
  File "/usr/local/lib/python2.7/dist-packages/pymongo-2.1.1-py2.7-linux-x86_64.egg/pymongo/connection.py", line 811, in _send_message
    sock = self.__socket()
  File "/usr/local/lib/python2.7/dist-packages/pymongo-2.1.1-py2.7-linux-x86_64.egg/pymongo/connection.py", line 674, in __socket
    host, port = self.__find_node()
  File "/usr/local/lib/python2.7/dist-packages/pymongo-2.1.1-py2.7-linux-x86_64.egg/pymongo/connection.py", line 659, in __find_node
    raise AutoReconnect(', '.join(errors))
pymongo.errors.AutoReconnect: could not connect to  localhost:8911: [Errno -5] No address associated with hostname, could not connect to localhost:8911: [Errno 111] Connection refused, could not connect to localhost:8912: [Errno 111] Connection refused, could not connect to  localhost:8912: [Errno -5] No address associated with hostname, localhost:8910 is not primary or master
>>> 
>>> 
>>> len(list(collection.find()))
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/usr/local/lib/python2.7/dist-packages/pymongo-2.1.1-py2.7-linux-x86_64.egg/pymongo/cursor.py", line 703, in next
    if len(self.__data) or self._refresh():
  File "/usr/local/lib/python2.7/dist-packages/pymongo-2.1.1-py2.7-linux-x86_64.egg/pymongo/cursor.py", line 666, in _refresh
    self.__uuid_subtype))
  File "/usr/local/lib/python2.7/dist-packages/pymongo-2.1.1-py2.7-linux-x86_64.egg/pymongo/cursor.py", line 616, in __send_message
    **kwargs)
  File "/usr/local/lib/python2.7/dist-packages/pymongo-2.1.1-py2.7-linux-x86_64.egg/pymongo/connection.py", line 880, in _send_message_with_response
    sock = self.__socket()
  File "/usr/local/lib/python2.7/dist-packages/pymongo-2.1.1-py2.7-linux-x86_64.egg/pymongo/connection.py", line 674, in __socket
    host, port = self.__find_node()
  File "/usr/local/lib/python2.7/dist-packages/pymongo-2.1.1-py2.7-linux-x86_64.egg/pymongo/connection.py", line 659, in __find_node
    raise AutoReconnect(', '.join(errors))
pymongo.errors.AutoReconnect: could not connect to  localhost:8911: [Errno -5] No 
address associated with hostname, could not connect to localhost:8911: [Errno 111] 
Connection refused, could not connect to localhost:8912: [Errno 111] Connection refused, 
could not connect to  localhost:8912: [Errno -5] No address associated with hostname, 
localhost:8910 is not primary or master
>>> 

Монго (Cli) выход

SECONDARY> rs.status()
{
        "set" : "myset",
        "date" : ISODate("2012-02-26T15:09:49Z"),
        "myState" : 2,
        "members" : [
                {
                        "_id" : 0,
                        "name" : "localhost:8910",
                        "health" : 0,
                        "state" : 8,
                        "stateStr" : "(not reachable/healthy)",
                        "uptime" : 0,
                        "optime" : {
                                "t" : 1330268443000,
                                "i" : 1
                        },
                        "optimeDate" : ISODate("2012-02-26T15:00:43Z"),
                        "lastHeartbeat" : ISODate("2012-02-26T15:09:37Z"),
                        "pingMs" : 0,
                        "errmsg" : "socket exception"
                },
                {
                        "_id" : 1,
                        "name" : "localhost:8911",
                        "health" : 1,
                        "state" : 2,
                        "stateStr" : "SECONDARY",
                        "optime" : {
                                "t" : 1330268443000,
                                "i" : 1
                        },
                        "optimeDate" : ISODate("2012-02-26T15:00:43Z"),
                        "self" : true
                },
                {
                        "_id" : 2,
                        "name" : "localhost:8912",
                        "health" : 0,
                        "state" : 8,
                        "stateStr" : "(not reachable/healthy)",
                        "uptime" : 0,
                        "optime" : {
                                "t" : 1330268443000,
                                "i" : 1
                        },
                        "optimeDate" : ISODate("2012-02-26T15:00:43Z"),
                        "lastHeartbeat" : ISODate("2012-02-26T15:09:37Z"),
                        "pingMs" : 0,
                        "errmsg" : "socket exception"
                }
        ],
        "ok" : 1
}
SECONDARY> 
SECONDARY> 
SECONDARY> db.TEST.find().count()
54
SECONDARY> db.TEST.insert({eeee:23232323})
not master
SECONDARY> 
SECONDARY> db.TEST.find().count()
54

Ответы [ 2 ]

4 голосов
/ 27 февраля 2012

Есть два фактора, чтобы решить эту проблему, ReplicaSetConnection и ReadPreference.SECONDARY.

т.е.

ReplicaSetConnection("localhost:8910,localhost:8911,localhost8912",  
      replicaSet='myset', read_prefererence=ReadPreference.SECONDARY) 
1 голос
/ 27 февраля 2012

используйте последнюю версию PyMongo и создайте экземпляр ReplicaSetConnection вместо Connection. Используйте ReadPreference для прямого чтения на первичную или вторичную; предпочтение может быть установлено в ReplicaSetConnection, а также переопределено для каждого запроса:

http://api.mongodb.org/python/current/api/pymongo/index.html#pymongo.ReadPreference

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...