视频

了解更多
相关电子书下载:内存型 NoSQL 数据库的重要性
运行 Redis SQL 查询不必困难。几年前,当我与一位在零售公司管理数据仓库解决方案的朋友交谈时,我提到了这一点。在他解释了他面临的一个问题后,我们开始讨论 Redis 的查询。
“我们的数据仓库解决方案有一个痛点。我们有一些用例需要在实时记录数据并执行分析操作。然而,有时需要几分钟才能获得结果。Redis 能在这里提供帮助吗?请记住,我们不能一次性彻底替换基于 SQL 的解决方案。我们只能一步一步来。”
现在,如果您和我的朋友面临同样的困境,我们有个好消息告诉您。有多种方法可以在不中断现有基于 SQL 的解决方案的情况下,运行 Redis 查询并将 Redis 引入您的架构中。
让我们来探讨一下如何实现这一点。但在进一步讨论之前,我们有一位 Redis 黑客马拉松参赛者创建了自己的应用程序,该应用程序允许您使用 SQL 查询 Redis 中的数据。
观看下方视频。
将表映射到 Redis 数据结构非常简单。最常用的数据结构如下:
一种方法是将每一行存储为一个哈希 (Hash),其键基于表的主键,并将该键存储在集合 (Set) 或有序集合 (Sorted Set) 中。
图 1 展示了如何将表映射到 Redis 数据结构的示例。在此示例中,我们有一个名为 Products 的表。每一行都被映射到一个哈希 (Hash) 数据结构。
主键 ID 为 10001 的行将作为哈希 (Hash) 存入,其键为 product:10001。在此示例中,我们有两个有序集合 (Sorted Set):第一个用于按主键遍历数据集,第二个用于按价格查询。
图 1. 将表映射到 Redis 数据结构
使用此选项,您需要修改代码以使用 Redis 查询而不是 SQL 命令。以下是一些 SQL 命令及其对应的 Redis 命令示例
A. 插入数据
SQL: insert into Products (id, name, description, price) values = (10200, “ZXYW”,“Description for ZXYW”, 300);
Redis: MULTI HMSET product:10200 name ZXYW desc “Description for ZXYW” price 300 ZADD product_list 10200 product:10200 ZADD product_price 300 product:10200 EXEC
B. 按产品 ID 查询
SQL: select * from Products where id = 10200
Redis: HGETALL product:10200
C. 按价格查询
SQL: select * from Product where price < 300
Redis: ZRANGEBYSCORE product_price 0 300
这将返回键:product:10001, product:10002, product:10003。现在对每个键运行 HGETALL。
HGETALL product:10001 HGETALL product:10002 HGETALL product:10003
现在,如果您希望在解决方案中保留 SQL 接口,而只将底层数据存储改为 Redis 以提高速度,那么您可以使用 Apache Spark 和 Spark-Redis 库来实现。
Spark-Redis 库允许您使用 DataFrame API 来存储和访问 Redis 数据。换句话说,您可以使用 SQL 命令插入、更新和查询数据,但数据在内部被映射到 Redis 数据结构。
首先,您需要下载 spark-redis 并构建库以获取 jar 文件。例如,对于 spark-redis 2.3.1,您将获得 spark-redis-2.3.1-SNAPSHOT-jar-with-dependencies.jar。
接下来您需要确保 Redis 实例正在运行。 在我们的示例中,我们将在 localhost 上运行 Redis,并使用默认端口 6379。
您也可以在 Apache Spark 引擎上运行查询。以下是如何实现的一个示例
$ spark-shell --jars spark-redis-2.3.1-SNAPSHOT-jar-with-dependencies.jar
scala> import org.apache.spark.sql.SparkSession scala> val spark = SparkSession .builder() .appName("redis-sql") .master("local[*]") .config("spark.redis.host","localhost") .config("spark.redis.port","6379").getOrCreate() scala> import spark.sql scala> import spark.implicits._ scala> sql("create table if not exists products(id string, name string, description string, price int) using org.apache.spark.sql.redis options (table 'product')") scala> sql("insert into products values = ('10200','ZXYW','Description of ZXYW', 300)") scala> val results = sql("select * from products") scala> results.show() +-----+----+-------------------+-----+ | id|name| description|price| +-----+----+-------------------+-----+ |10200|ZXYW|Description of ZXYW| 300| +-----+----+-------------------+-----+
现在您还可以使用 Redis 客户端以 Redis 数据结构的形式访问这些数据
127.0.0.1:6379> keys product* 1) "product:2e3f8611dbe94a588706a2aaea547caa"
一种更有效的方法是使用 scan 命令,因为它允许您在遍历数据时进行分页。
127.0.0.1:6379> scan 0 match product* 1) "3" 2) 1) "product:2e3f8611dbe94a588706a2aaea547caa" 127.0.0.1:6379> hgetall product:2e3f8611dbe94a588706a2aaea547caa 1) "name" 2) "ZXYW" 3) "price" 4) "300" 5) "description" 6) "Description of ZXYW" 7) "id" 8) "10200"
至此,我们介绍了两种在不中断的情况下运行 Redis SQL 查询的简单方法。更进一步,您可能希望在我们最新的白皮书中了解为什么您的 SQL Server 需要 Redis。
但关于使用 Redis 处理实时数据,这只是您可以用来提供实时体验的众多方法之一。
如果您想了解 Redis 如何保证实时数据传输,请务必联系我们。