我正在使用uwsgi + nginx并使用aws elasticache(redis 2.8.24)运行python应用程序(flask + redis-py).
在尝试改善我的应用程序响应时间的同时,我注意到在高负载下(使用loader.io每秒500请求/ 30秒)我正在丢失请求(对于此测试我只使用一台没有负载的服务器平衡器,1个uwsgi实例,4个进程,用于测试).

我挖得更深一点,发现在这个负载下,对ElastiCache的一些请求很慢.例如:
我的AWS ElastiCache基于cache.m4.xlarge上的2个节点(默认AWS配置设置).查看过去3小时内连接的当前客户端:

我认为这没有意义,因为目前有14台服务器(其中8台具有XX RPS的高流量使用这个集群),我希望看到更高的客户端速率.
uWSGI config(版本2.0.5.1)
processes = 4
enable-threads = true
threads = 20
vacuum = true
die-on-term = true
harakiri = 10
max-requests = 5000
thread-stacksize = 2048
thunder-lock = true
max-fd = 150000
# currently disabled for testing
#cheaper-algo = spare2
#cheaper = 2
#cheaper-initial = 2
#workers = 4
#cheaper-step = 1
Run Code Online (Sandbox Code Playgroud)
Nginx只是使用unix socket的uWSGI的web代理.
这是我打开redis连接的方式:
rdb = [
redis.StrictRedis(host='server-endpoint', …Run Code Online (Sandbox Code Playgroud) 目前我使用基本mset功能来存储键/值;
from common.redis_client import get_redis_client
cache = get_redis_client()
for k,v in some_dict.items():
kw = {'key': value}
cache.mset(kw)
#later:
cache.get('key')
Run Code Online (Sandbox Code Playgroud)
我分别存储每个键/值(例如,不是在一个json中)因为存储整个dict会把它变成一个字符串,并且需要我在存储和检索时序列化/反序列化,我真的需要访问单独的键/值.
我的问题::有没有办法可以同时使用mset多个键/值?而不是多次写入redis数据库?反之亦然,我可以在一次访问中有多个读取(get)吗?(是的 - 我有很多redis活动正在进行并且负载很重.我确实关心这个)
我在服务器中运行代码时遇到此错误,我的环境是debian,并且 Python2.7.3
Traceback (most recent call last):
File "fetcher.py", line 4, in <module>
import mirad.fetcher_tasks as tasks
File "/home/mirad/backend/mirad/fetcher_tasks.py", line 75, in <module>
redis_keys = r.keys('*')
File "/home/mirad/backend/venv/local/lib/python2.7/site-packages/redis/client.py", line 863, in keys
return self.execute_command('KEYS', pattern)
File "/home/mirad/backend/venv/local/lib/python2.7/site-packages/redis/client.py", line 534, in execute_command
connection.send_command(*args)
File "/home/mirad/backend/venv/local/lib/python2.7/site-packages/redis/connection.py", line 532, in send_command
self.send_packed_command(self.pack_command(*args))
File "/home/mirad/backend/venv/local/lib/python2.7/site-packages/redis/connection.py", line 508, in send_packed_command
self.connect()
File "/home/mirad/backend/venv/local/lib/python2.7/site-packages/redis/connection.py", line 412, in connect
raise ConnectionError(self._error_message(e))
redis.exceptions.ConnectionError: Error -2 connecting to localhost:6379. Name or service not known.
Run Code Online (Sandbox Code Playgroud)
当我运行redis-cli它正常工作没有任何错误:
$ redis-cli …Run Code Online (Sandbox Code Playgroud) 我正在尝试按照此Redis 文档链接创建一个可实时搜索的名人小型数据库(使用 Python 客户端)。
我尝试了类似的代码,但最后一行(按“s”查询)应该返回两个文档,而是返回一个空白集。有人可以帮我找出我所犯的错误吗?
import redis
from redis.commands.json.path import Path
import redis.commands.search.aggregation as aggregations
import redis.commands.search.reducers as reducers
from redis.commands.search.field import TextField, NumericField, TagField
from redis.commands.search.indexDefinition import IndexDefinition, IndexType
from redis.commands.search.query import NumericFilter, Query
d1 = {"key": "shahrukh khan", "pl": '{"d": "mvtv", "id": "1234-a", "img": "foo.jpg", "t: "act", "tme": "1965-"}', "org": "1", "p": 100}
d2 = {"key": "salman khan", "pl": '{"d": "mvtv", "id": "1236-a", "img": "fool.jpg", "t: "act", "tme": "1965-"}', "org": "1", "p": 100}
d3 = {"key": …Run Code Online (Sandbox Code Playgroud) 当超过一定数量的用户(大约1200个并发用户)时,我收到“打开文件太多错误”信息。
我使用这个增加了限制,但是却遇到了同样的错误。
然后,我遵循了这一步骤,没有任何变化得到相同的错误。
为了创建连接,我在Django设置中使用了REDIS它,并在需要时使用它。
REDIS = redis.StrictRedis(host='localhost', port=6379, db=0)
Run Code Online (Sandbox Code Playgroud)
我之所以这样做,是因为它在redis邮件列表中建议如下:
一种。创建一个全局redis客户实例,并让您的代码使用它。
这种方法适合连接池吗?或者如何避免打开文件过多的错误?在Django响应中
连接错误(由:[Errno 24]打开的文件太多)“,),)'
谢谢。
以下代码示例将通过 Python REPL 和 redis-cli 完成/编写。
Redis 服务器 v=2.8.4
背景:将长时间运行的键(哈希)存储在 Redis 键值存储中,然后尝试将另一个键(具有相同名称,但不同类型 - 字符串)存储在同一键值存储中。
首先是代码,然后是问题:
>>> import redis
>>> db = redis.Redis(
... host='127.0.0.1',
... port=6379,
... password='',
... db=3)
>>> db.hset("123456", "field1", True)
1
>>> db.type("123456")
b'hash'
>>> db.hgetall("123456")
{b'field1': b'True'}
>>> db.set("123456", "new-value")
True
>>> db.type("123456")
b'string'
>>> db.get("123456")
b'new-value'
Run Code Online (Sandbox Code Playgroud)
您首先会注意到 SET 选项覆盖了 HSET。现在,当我尝试用以下内容覆盖 SET 时:
>>> db.lset("123456", "list1", "list1value")
Traceback (most recent call last):
...
redis.exceptions.ResponseError: WRONGTYPE Operation against a key holding the wrong kind of value …Run Code Online (Sandbox Code Playgroud) 应该两个不同的模块如何foo.py和bar.py获得从Redis的连接池中的连接?换句话说,我们应该如何构建应用程序?
我相信目标是让所有模块只有一个连接池来获取连接。
Q1:在我的例子中,两个模块是否从同一个连接池中获得连接?
Q2:在 中创建 RedisClient 实例RedisClient.py,然后将实例导入其他 2 个模块是否可以?或者,还有更好的方法?
Q3:conn实例变量的延迟加载真的有用吗?
RedisClient.py
import redis
class RedisClient(object):
def __init__(self):
self.pool = redis.ConnectionPool(host = HOST, port = PORT, password = PASSWORD)
@property
def conn(self):
if not hasattr(self, '_conn'):
self.getConnection()
return self._conn
def getConnection(self):
self._conn = redis.Redis(connection_pool = self.pool)
redisClient = RedisClient()
Run Code Online (Sandbox Code Playgroud)
文件
from RedisClient import redisClient
species = 'lion'
key = 'zoo:{0}'.format(species)
data = redisClient.conn.hmget(key, 'age', 'weight')
print(data)
Run Code Online (Sandbox Code Playgroud)
酒吧.py
from RedisClient import redisClient …Run Code Online (Sandbox Code Playgroud) 我有一个大约有 350,000 个键的数据库。目前我的代码只是遍历所有键并从数据库中获取它的值。
然而,这需要将近 2 分钟才能完成,这似乎很慢,redis-benchmark给了 100k reqs/3s。
我看过流水线,但我需要返回每个值,以便我最终得到一个键值对的字典。
目前,如果可能的话,我正在考虑在我的代码中使用线程来加快速度,这是处理这个用例的最佳方法吗?
这是我到目前为止的代码。
import redis, timeit
start_time = timeit.default_timer()
count = redis.Redis(host='127.0.0.1', port=6379, db=9)
keys = count.keys()
data = {}
for key in keys:
value = count.get(key)
if value:
data[key.decode('utf-8')] = int(value.decode('utf-8'))
elapsed = timeit.default_timer() - start_time
print('Time to read {} records: '.format(len(keys)), elapsed)
Run Code Online (Sandbox Code Playgroud) redis 版本 3.4.1 必须使用 hash,不能使用 str 或其他数据类型数据:
{'_anno': {
'ctp': 'list',
'dt': [],
'ml': 0,
'na': 'apple',
'pos': -1,
'rel': '',
'st_var': '',
'tp': 'object'},
'_att': {'_cuser': 'apple card',
'_last_editor': 'apple card',
'_protext': 'authorize',
'_status': 'normal',
'_theme_id': 'apple card',
'_view': '12'},
}
Run Code Online (Sandbox Code Playgroud)
我的代码
pool = redis.ConnectionPool(host=host, port=port)
conn = redis.StrictRedis(connection_pool=pool)
conn.hmset("aaaaaa",data)
Run Code Online (Sandbox Code Playgroud)
引发错误
数据错误:类型无效的输入:'dict'。首先转换为字节、字符串、整数或浮点数。
现在代码
pool = redis.ConnectionPool(host=host, port=port)
conn = redis.StrictRedis(connection_pool=pool)
new_data={}
for key,value in data.items():
new_data[key]=json.dumps(value)
conn.hmset("aaaaaa",new_data)
Run Code Online (Sandbox Code Playgroud)
有没有更pythonic的方式?
当我尝试按照此处的部署指南连接到主节点时,我遇到了 MasterNotFoundError: https: //docs.bitnami.com/tutorials/deploy-redis-sentinel-product-cluster/
我连接到主 Redis Sentinel 节点的代码是:
from redis.sentinel import Sentinel
redis_host = 'redis.default.svc.cluster.local'
redis_port = 26379
sentinel = Sentinel([(redis_host, redis_port)], socket_timeout=0.1, password='abc')
redis_client = sentinel.master_for('mymaster', password='abc')
Run Code Online (Sandbox Code Playgroud)
在他们的GitHub 存储库中,我看到 Sentinel.masterSet 的配置默认设置为 mymaster。但是当我尝试使用下面的代码递增时:
redis_client.incr('counter', 1)
Run Code Online (Sandbox Code Playgroud)
我面临 redis.sentinel.MasterNotFoundError: No master found for 'mymaster' 错误。
我该如何解决这个问题?谢谢。