rails基础-使用redis记录点赞数

为什么使用redis

社交平台每天的点赞操作都非常的多,如果每一次的点赞都写入数据库,对数据库而言是一个非常大的负担,因此使用redis记录点赞数,再每天定时写入库中做持久化是一个理想的解决方法。

redis 数据结构

redis中有5种数据结构,string、hash、list、zset、 set

结构类型 操作 存储的值 读写能力
string set get 字符串、整数、浮点数 对整个字符串或者字符串的其中一部分执行操作;整数和浮点数执行自增(increment)或者自减(decrement)
hash hmset hget hgetall hash散列,特别适合用于存储对象 添加、获取、移除单个键值对;获取所有键值对
list lpush lrange 链表,每个节点都包含一个字符串 从链表的两端推入或者弹出元素;读取单个或者多个元素;根据值来查找或者移除元素
set sadd smembers String 类型的无序集合,集合中不能出现重复的数据 添加、获取、移除单个元素;检查一个元素是否存在于某个集合中;计算交集、并集;获取集合中随机元素
zset zadd String 类型的有序集合

在rails项目中实现点赞统计

安装redis

# gemfile

gem 'redis'
gem 'redis-rails'

# bundle 

设置redis连接

# services/redis_client.rb
class RedisClient
    def self.current
      @redis_client ||= Redis.new(
          url: redis_url,               #redis 服务器地址
          password: redis_password      #redis 服务器密码
        )
    end
end

#接下来在项目中就可以使用RedisClient.current 去连接redis

模版

点赞需要记录 哪位用户(user) 对什么文章(article)点赞或取消点赞
需要记录 哪篇文章(article)点赞的总数 (thumbs_up_count)

RedisClient.current.hmset('thumbs_up', ["#{ariticle_id}#{user_id}", 0]])
RedisClient.current.set("thumbs_up
#{article_id}", up_count)

class User < ActiveRecord::Base

end

class Article < ActiveRecord::Base       #up_count 统计所有赞

end

class ThumbsUpLog < ActiveRecord::Base   # user_id article_id status 

end

操作

设定 1 为点赞 2 为取消点赞

class ArticleControllers < ApplicationController
    # @params article_id user_id operate
    def thumbs_up
        article_id, user_id = params[:article_id], params[:user_id]
        RedisClient.current.hmset("thumbs_up", ["#{article_id}_#{user_id}",operate ])
        if operate == 1
           RedisClient.current.incr("thumbs_up_#{article_id}")
        elsif operate == 2 && RedisClient.current.get("thumbs_up_#{article_id}") > 1
           RedisClient.current.decr("thumbs_up_#{article_id}")
        end
    end
end

定时任务

这里的定时任务采用之前写过的sidekiq-cron去实现

class SyncThumbsUpJob < ActiveJob::Base
    queue_as :default
    
    def perform
        Article.find_each do |a|
            up_count = RedisClient.current.get("thumbs_up_#{a.id}")
            a.udpate!(up_count: up_count)
        end
       
        sync_thumbs_up_log
        
    end
    
    def sync_thumbs_up_log 
        hash = RedisClient.current.hgetall('thumbs_up')
        hash.keys.each do |k|
            aritcle_id, user_id =  k.split('_')
            log = ThumbsUpLog.where(user_id: user_id, aritcle_id: aritcle_id).first_or_initialize
            log.udpate!(status: hash[k.to_sym])
        end
    end
end

总结

基本的思路如此: 将用户赞或取消赞都放到redis中,在设置一个定时任务去做数据持久化

后面都job感觉不理想,有感兴趣的说说好的思路吗

你可能感兴趣的:(rails基础-使用redis记录点赞数)