【问题标题】:redis high response time when searching with regex使用正则表达式搜索时redis的高响应时间
【发布时间】:2018-02-11 12:20:33
【问题描述】:

我将 redis 用于我的主数据库 (mongodb) 缓存系统。 一切正常,直到缓存的文档计数变大,例如在缓存 15K 文档后,redis 响应时间增加。

这是我在 Redis 中的 key、value

key: userId_123_username_test_email_test@gmail.com
value: JSON.stringfy(userobject)

正如我在标题中所说,当我尝试使用正则表达式查找文档时,响应时间会增加。

我正在寻找索引文档,我发现了这个article

根据这篇文章,我发现我可以为年龄字段设置索引,但实际上我需要为电子邮件或用户名设置索引

HMSET user:1 id 1 username antirez ctime 1444809424 age 38
ZADD user.age.index 38 1

也试试这个:

ZADD user.username.index antirez 1

返回错误: ERR 值不是有效的浮点数

【问题讨论】:

    标签: node.js regex caching redis


    【解决方案1】:

    ERR value is not a valid float 是因为:

    分数值应该是双精度浮点数的字符串表示。 +inf 和 -inf 值也是有效值。

    所以你不应该在 sortedset 值中使用电子邮件或用户名,你可以尝试另一种方法来构建二级索引:字典索引,在你提到的文章中也提到了。

    在此方法中,只需将值设置为 0 并使用成员的 lex order 来构建索引。例如。如果你想为用户名建立索引:

    ZADD user.username.index 0 antirez:1
    

    所以当你想找到名字为antirez的id时,你可以这样做:

    ZRANGEBYLEX user.username.index [antirez + limit 1 1
    

    [ 表示包容,+ 表示无限大,它只会返回一个成员,例如antirez:1,然后你用冒号分割字符串,你会得到antirez的id。电子邮件与用户名相同。

    更新评论:

    是的,你可以让复合索引之类的东西喜欢关系数据库。但它也需要有一个命令,比如(用户名,ctime,...)。

    例如如果你想用 username 和 ctime 建立一个复合索引:

    ZADD user.composite.index 0 antirez:2017-09-04:1
    

    当你想获取带有用户名和 ctime 的 id 时:

    ZRANGEBYLEX user.composite.index [antirez:2017-09-04 (antirez:2017-09-05 
    

    它会返回这段时间内的所有id,它的用户名是antirez。

    总之,你可以使用 sortedset 来构建一个类似于 rdb 的索引的索引。

    如果索引是(key1,key2,key3),那么你应该将成员的前缀设置为“key1:key2:key3:”,然后在这个字符串中添加一个参考值或真实值,如: "key1:key2:key3:ref_value",并将所有成员的值设置为相等。 SortedSet 将按其 lex 顺序对所有成员进行排序,因此您可以使用复合索引的前缀来索引,例如:key1、key1:key2 或 key1:key2:key3。

    对于使用 ref value 或 real value 存储,也许 ref_value 更灵活,您可以将 real value 存储为其他数据类型,可以是 list 或 hash 或 set。当你想更新一些东西时,你可以先使用二级索引来获取它的 ref_value,然后去它的 real_value 去改变它。

    【讨论】:

    • 当我更改ZRANGEBYLEX user.username.index [antirez + limit 0 1时它工作了,谢谢♥
    • 有什么方法可以找到两个或两个以上的索引,例如我想要这样的东西 ZRANGEBYLEX user.username.index [antirez + limit 0 1 user.ctime.index [1444809424 + limit 0 1 并且我也索引了它们中的 both (用户名, ctime)
    • 它的工作,但实际上我需要找到未排序的索引是这样的:(uname,email,ctime)或(email,ctime,uname,...)或其他
    • `(uname, email, ctime)`和`(email, ctime, uname,...)`有什么区别,你可以按照你指定的顺序订购,然后他们将是相同的。
    • 在这种情况下,您应该将 order 设置为 (uname, ctime, email),然后您可以使用前两个键查找,zadd 应该像 ZADD user.composite.index 0 uname:ctime:email:id 和 find ZRANGEBYLEX user.composite.index [uname:ctime + limit 0 1 如果您没有电子邮件密钥。
    【解决方案2】:
    return error: ERR value is not a valid float is because the order is wrong
    Try zadd user.username.index 1 antirez
    
    127.0.0.1:6379> zadd user.username.index 1 antirez 
    Response: (integer) 1
    
    127.0.0.1:6379> zrange user.username.index 0 -1 withscores
    

    1) “反雷兹”

    2) “1”

    127.0.0.1:6379>
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-03-20
      • 1970-01-01
      相关资源
      最近更新 更多