Ruby通过Lua脚本提高Redis查询性能

基于Ruby的reids-rb gem包

首先,我简单介绍一下,本文中案例的基本场景,即,在一个博客系统中,将所有的评论存储或缓存到Redis中,当我们需要分页取出评论的过程。

初始化数据到Redis,我们将会用到中Redis的两种类型,一个是Hash,另一个是Zset(有序集合)。zset主要是用来存储评论的id和评论的时间,用于分页取评论信息,hash中存储的是每一条评论的具体信息。

keys: article:id:comments comment:id:id

基于redis-rb 公共代码

  1. Gemfile
source 'https://rubygems.org'
gem 'redis'
  1. redis_client.rb
require 'redis'

$redis = Redis.new(host: '127.0.0.1', port: 6379)

使用Redis的方式查询

ruby代码

  def self.get_comment_by_article(article_id, last_time, per_page = 10)
      comment_hash = []
      comment_ids = $redis.zrevrangebyscore("article:#{article_id}:comments", last_time, 0, limit: [0, per_page])
      comment_ids.each do |item|
        comment_hash << $redis.hgetall("comment:id:#{item}")
      end

      return comment_hash
    end

使用Lua的方式查询

  1. Lua 脚本
-- get-comment-by-article_id

local rep = {}
local comment_ids_table = redis.call('ZREVRANGEBYSCORE', KEYS[1], ARGV[1], ARGV[2], 'LIMIT', 0, ARGV[3] )
for i, v in pairs(comment_ids_table) do
  local comment_key = string.format("comment:id:%d", v)
  table.insert(rep,redis.call('hgetall', comment_key))
end
return rep
  1. Ruby实现代码
  def self.get_comment_by_article(article_id, last_time, per_page = 10)
      # 获取Lua脚本
      lua_script = nil
      File.open("lib/get-article-by-post.lua") do |file|
        lua_script = file.read()
      end
      script_sha1 = Digest::SHA1.hexdigest(lua_script)
      keys = [ "article:#{article_id}:comments" ]
      args = [ last_time, 0, per_page ]

      # 执行redis.eval
      comment_list = []
      begin
         comment_list = $redis.evalsha(script_sha1, keys, args)
      rescue => e
        if e.message.match(/NOSCRIPT/)
           comment_list = $redis.eval(lua_script, keys, args)
        else
          raise
        end
      end

      # 处理查询结果
      comment_hash = []
      comment_list.each do |item|
         comment_hash << Hash[*item]
      end

      return comment_hash
    end

性能对比

代码

require 'benchmark'
require_relative 'lib/lua_redis_fetch'
require_relative 'lib/redis_fetch'

puts "#{'#' * 10} -- benchmark -- #{'#' * 10}"

lua_redis_time = Benchmark.realtime do
  Lua::LuaRedisFetch.get_comment_by_article(1, Time.now.to_f)
end

puts "lua fetch: #{lua_redis_time}"


redis_time = Benchmark.realtime do
  RedisRb::RedisFetch.get_comment_by_article(1, Time.now.to_f)
end

puts "redis fetch: #{redis_time}"

运行结果

########## -- benchmark -- ##########
lua fetch: 0.0016556469781789929
redis fetch: 0.003393028018763289

明显看出使用lua脚本的性能较高,现在使用的Redis是本来redis,当项目上线后使用远程Redis,lua的性能更能够体现出来。不适用lua脚本,会有多次Redis连接通信,网络损耗较大。

建议

  1. 当进行简单的单条数据查询使用原生redis查询
  2. 当进行复杂的查询使用Lua能显著提高查询性能
  3. 使用Lua脚本能减少同Redis 的网络通信
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,324评论 5 476
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,303评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,192评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,555评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,569评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,566评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,927评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,583评论 0 257
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,827评论 1 297
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,590评论 2 320
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,669评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,365评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,941评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,928评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,159评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,880评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,399评论 2 342

推荐阅读更多精彩内容