您将学习存储和检索数据的两种技术。当选择要在应用程序中使用的方法时,请根据数据访问模式选择可简化架构的方法。
但首先要确保您可以连接到 Redis。
完成模块所需时间:60 分钟
返回 ElastiCache 控制面板:
syntax: shell
$ python
如果命令挂起,请参阅示例后面的说明。
syntax: python
syntax: python >>> import redis >>> client = redis.Redis.from_url('redis://endpoint:6379') >>> client.ping() True
$ export REDIS_URL=redis://your_redis_endpoint:6379/ $ export DB_HOST=your_mysql_endpoint $ export DB_USER=admin $ export DB_PASS=your_admin_password $ export DB_NAME=tutorial
请注意,mysql_endpoint、redis_endpoint 和 password 的值是您在前面步骤中保存的值。
代码示例中实施的两种方法中的第一种方法会缓存 SQL 查询结果的序列化表示。以下 Python 代码段展示了此逻辑:
syntax: python
def fetch(sql): result = cache.get(sql) if result: return deserialize(result) else: result = db.query(sql) cache.setex(sql, ttl, serialize(result)) return result
首先,在 Redis 中将 SQL 语句用作键,然后检查缓存以查看是否存在值。如果值不存在,则使用 SQL 语句查询数据库。数据库查询结果存储在 Redis 中。必须根据应用程序的性质,将 ttl 变量设置为合理的值。当 ttl 过期时,Redis 将移出键并释放相关内存。这段代码可以在教程存储库中找到,您可以按原样运行,但是如果希望在某个时间点查看某个变量的值,可以随意在各处添加 print 语句。
从策略角度看,此方法的缺点是,当数据库中的数据被修改时,如果先前的结果已缓存,且其 ttl 还没有过期,则这些更改不会自动反映给用户。
如何使用 fetch 函数的示例:
syntax: python
print(fetch("SELECT * FROM planet"))
结果将为:
syntax: python
[{'id': 10, 'name': 'Mercury'}, {'id': 11, 'name': 'Venus'}, {'id': 12, 'name': 'Earth'}, {'id': 13, 'name': 'Mars'}, {'id': 14, 'name': 'Jupiter'}, {'id': 15, 'name': 'Saturn'}, {'id': 16, 'name': 'Uranus'}, {'id': 17, 'name': 'Neptune'}]
当然,这是一个非常基本的示例,但是您的应用程序可以通过实施这种缓存模式而获益颇丰,在这种模式中,来自缓存的结果与直接来自数据库的结果没有差别。
您将实施的第二个示例将数据库记录映射到 Redis 哈希:
syntax: python
def planet(id): key = "planet:" + str(id) result = cache.hgetall(key) if result: return result else: sql = "SELECT `id`, `name` FROM `planet` WHERE `id`=%s" result = db_record(sql, (id,)) if result: cache.hmset(key, result) cache.expire(key, ttl) return result
Redis 中的键空间为平面,但是有一个惯例是通过使用冒号分隔的字符串来模拟结构。在本例中,ID 为 1 的记录的键采用“planet:1”。虽然此代码段足以展示一个通用模式,但是可以进一步抽象:一个模块负责生成键,另一个模块负责构建 SQL 字符串等等。此外,在您所使用的编程语言中也可能存在为此目的而构建的工具。
该示例从缓存或数据库检索记录,同样,可以有一个函数负责将对象持久存储到数据库。
在这两个示例中,您使用了生存时间 (ttl),该时间过后,Redis 将移出键。虽然这在大多数情况下已足以满足要求,但是您可能希望尽快从缓存中删除陈旧数据。如果确实需要如此,请确保检查其他选项,如直写缓存策略。本教程末尾提供了更多信息的链接。为满足您的好奇心,需要值得一提的是:虽然示例使用了 EXPIRE 命令,但 Redis 也提供了 EXPIREAT,用于指定应移出键的确切日期和时间。它使用的参数是一个绝对 Unix 时间戳(即,从 1970 年 1 月 1 日开始的秒数)。
当数据量超过配置的 maxmemory 设置时,Redis 将根据选择的移出策略采用不同的方法做出响应。默认情况下,ElastiCache for Redis 配置为从内存中删除设置了 ttl 且最近最少使用的键。移出策略参数称为 maxmemory-policy,ElastiCache 中的默认值为 volatile-lru。此使用案例的另一个有趣选项是 volatile-ttl 策略,它指示 Redis 通过删除那些 ttl 最短的键来回收内存。
实施此策略后,请确保对您的应用程序进行测试,以确定最佳 ttl 值和最佳移出策略。使用空缓存和满缓存检查应用程序的性能。