Make Gnocchi connection pool configurable

When CloudKitty is collecting data from Gnocchi, it opens many
connections to Gnocchi to parallelize the requests; as CloudKitty starts
to fetch the responses from Gnocchi, it releases the connections to the
pool until it starts to overflow (reaching the default limit of the
Requests connection pool). This behavior causes no problems, but
prevents the reuse of connections.

To mitigate this problem and optimize the use of connections, we propose
to add a new configuration in Gnocchi collector and fetcher to set the
connection pool maximum size when connecting to Gnocchi. The new
configuration is `http_pool_maxsize` and you can configure it in the
`cloudkitty.conf` file like:

```
[fetcher_gnocchi]
http_pool_maxsize = 50

[collector_gnocchi]
http_pool_maxsize = 50
```

The default value is defined by the `requests` library which is 10.

Change-Id: I3ee22984dc87b505924e1711bc723bc1c5f160a5
Story: 2008125
Task: 40847
This commit is contained in:
pedro 2020-02-20 17:31:23 -03:00 committed by Pierre Riteau
parent cbcdacac61
commit 7864529c19
4 changed files with 63 additions and 2 deletions

View File

@ -14,6 +14,7 @@
# under the License. # under the License.
# #
from datetime import timedelta from datetime import timedelta
import requests
import six import six
from gnocchiclient import auth as gauth from gnocchiclient import auth as gauth
@ -30,6 +31,7 @@ from voluptuous import Required
from voluptuous import Schema from voluptuous import Schema
from cloudkitty import collector from cloudkitty import collector
from cloudkitty.common import custom_session
from cloudkitty import dataframe from cloudkitty import dataframe
from cloudkitty import utils as ck_utils from cloudkitty import utils as ck_utils
from cloudkitty.utils import tz as tzutils from cloudkitty.utils import tz as tzutils
@ -67,6 +69,12 @@ collector_gnocchi_opts = [
default='RegionOne', default='RegionOne',
help='Region Name', help='Region Name',
), ),
cfg.IntOpt(
'http_pool_maxsize',
default=requests.adapters.DEFAULT_POOLSIZE,
help='If the value is not defined, we use the value defined by '
'requests.adapters.DEFAULT_POOLSIZE',
)
] ]
ks_loading.register_session_conf_options(cfg.CONF, COLLECTOR_GNOCCHI_OPTS) ks_loading.register_session_conf_options(cfg.CONF, COLLECTOR_GNOCCHI_OPTS)
@ -150,7 +158,9 @@ class GnocchiCollector(collector.BaseCollector):
self._conn = gclient.Client( self._conn = gclient.Client(
'1', '1',
session_options={'auth': auth_plugin, 'verify': verify}, session=custom_session.create_custom_session(
{'auth': auth_plugin, 'verify': verify},
CONF.collector_gnocchi.http_pool_maxsize),
adapter_options=adapter_options, adapter_options=adapter_options,
) )

View File

@ -0,0 +1,32 @@
# -*- coding: utf-8 -*-
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License. You may obtain
# a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.
#
import logging
import requests
from keystoneauth1 import session as ks_session
LOG = logging.getLogger(__name__)
def create_custom_session(session_options, pool_size):
LOG.debug("Using custom connection pool size: %s", pool_size)
session = requests.Session()
session.adapters['http://'] = ks_session.TCPKeepAliveAdapter(
pool_maxsize=pool_size)
session.adapters['https://'] = ks_session.TCPKeepAliveAdapter(
pool_maxsize=pool_size)
return ks_session.Session(session=session, **session_options)

View File

@ -13,12 +13,15 @@
# License for the specific language governing permissions and limitations # License for the specific language governing permissions and limitations
# under the License. # under the License.
# #
import requests
from gnocchiclient import auth as gauth from gnocchiclient import auth as gauth
from gnocchiclient import client as gclient from gnocchiclient import client as gclient
from keystoneauth1 import loading as ks_loading from keystoneauth1 import loading as ks_loading
from oslo_config import cfg from oslo_config import cfg
from oslo_log import log from oslo_log import log
from cloudkitty.common import custom_session
from cloudkitty import fetcher from cloudkitty import fetcher
@ -61,6 +64,12 @@ gfetcher_opts = [
default='RegionOne', default='RegionOne',
help='Region Name', help='Region Name',
), ),
cfg.IntOpt(
'http_pool_maxsize',
default=requests.adapters.DEFAULT_POOLSIZE,
help='If the value is not defined, we use the value defined by '
'requests.adapters.DEFAULT_POOLSIZE',
)
] ]
@ -105,7 +114,9 @@ class GnocchiFetcher(fetcher.BaseFetcher):
self._conn = gclient.Client( self._conn = gclient.Client(
'1', '1',
session_options={'auth': auth_plugin, 'verify': verify}, session=custom_session.create_custom_session(
{'auth': auth_plugin, 'verify': verify},
CONF.fetcher_gnocchi.http_pool_maxsize),
adapter_options=adapter_options, adapter_options=adapter_options,
) )

View File

@ -0,0 +1,8 @@
---
features:
- |
Adds a new configuration ``http_pool_maxsize`` that defines the maximum
size of Gnocchi's fetcher and collector HTTP connection pools.
The default value of this new configuration is defined by the ``requests``
library in the ``requests.adapters.DEFAULT_POOLSIZE`` global variable.