mirror of
https://github.com/outbackdingo/patroni.git
synced 2026-08-25 14:53:37 +00:00
Avoid unnecessary updates of the members ZNode. (#2115)
When deciding whether the ZNode should be updated we rely on the cached version of the cluster, which is updated only when members ZNodes are deleted/created or the `/status`, `/sync`, `/failover`, `/config`, or `/history` ZNodes are updated. I.e. after the update of the current member ZNode succeeded the cache becomes stale and all further updates are always performed even if the value didn't change. In order to solve it, we introduce the new attribute in the Zookeeper class and will use it for memorizing the actual value and for later comparison.
This commit is contained in:
@@ -105,6 +105,7 @@ class ZooKeeper(AbstractDCS):
|
||||
|
||||
self._fetch_cluster = True
|
||||
self._fetch_status = True
|
||||
self.__last_member_data = None
|
||||
|
||||
self._orig_kazoo_connect = self._client._connection._connect
|
||||
self._client._connection._connect = self._kazoo_connect
|
||||
@@ -348,11 +349,11 @@ class ZooKeeper(AbstractDCS):
|
||||
def touch_member(self, data, permanent=False):
|
||||
cluster = self.cluster
|
||||
member = cluster and cluster.get_member(self._name, fallback_to_leader=False)
|
||||
encoded_data = json.dumps(data, separators=(',', ':')).encode('utf-8')
|
||||
member_data = self.__last_member_data or member and member.data
|
||||
if member and (self._client.client_id is not None and member.session != self._client.client_id[0] or
|
||||
not (deep_compare(member.data.get('tags', {}), data.get('tags', {})) and
|
||||
member.data.get('version') == data.get('version') and
|
||||
member.data.get('checkpoint_after_promote') == data.get('checkpoint_after_promote'))):
|
||||
not (deep_compare(member_data.get('tags', {}), data.get('tags', {})) and
|
||||
member_data.get('version') == data.get('version') and
|
||||
member_data.get('checkpoint_after_promote') == data.get('checkpoint_after_promote'))):
|
||||
try:
|
||||
self._client.delete_async(self.member_path).get(timeout=1)
|
||||
except NoNodeError:
|
||||
@@ -361,13 +362,15 @@ class ZooKeeper(AbstractDCS):
|
||||
return False
|
||||
member = None
|
||||
|
||||
encoded_data = json.dumps(data, separators=(',', ':')).encode('utf-8')
|
||||
if member:
|
||||
if deep_compare(data, member.data):
|
||||
if deep_compare(data, member_data):
|
||||
return True
|
||||
else:
|
||||
try:
|
||||
self._client.create_async(self.member_path, encoded_data, makepath=True,
|
||||
ephemeral=not permanent).get(timeout=1)
|
||||
self.__last_member_data = data
|
||||
return True
|
||||
except Exception as e:
|
||||
if not isinstance(e, NodeExistsError):
|
||||
@@ -375,6 +378,7 @@ class ZooKeeper(AbstractDCS):
|
||||
return False
|
||||
try:
|
||||
self._client.set_async(self.member_path, encoded_data).get(timeout=1)
|
||||
self.__last_member_data = data
|
||||
return True
|
||||
except Exception:
|
||||
logger.exception('touch_member')
|
||||
|
||||
@@ -213,6 +213,7 @@ class TestZooKeeper(unittest.TestCase):
|
||||
self.zk.touch_member({'retry': 'retry'})
|
||||
self.zk._fetch_cluster = True
|
||||
self.zk.get_cluster()
|
||||
self.zk.touch_member({'retry': 'retry'})
|
||||
self.zk.touch_member({'conn_url': 'postgres://repuser:rep-pass@localhost:5434/postgres',
|
||||
'api_url': 'http://127.0.0.1:8009/patroni'})
|
||||
|
||||
|
||||
Reference in New Issue
Block a user