Redis实战读书分享1

45次阅读

共计 3294 个字符,预计需要花费 9 分钟才能阅读完成。

目前啊,公司有些动荡,程序员?‍? 真是不容易呀。自己趁着空余的时间,将原来看过的书和知识点再捋一遍。

ps:
纯手打,希望大家多多关注和点赞,后续陆续更新,希望大家一起进步!
图片使用的是 processOn 画的,有兴趣的小伙伴可以去试一下
如果同学需要 电子书 ,可以评论区留言
吐槽 processon,非会员文件最多 9 个,坑!

第一部分 入门

第一章 初识 redis

1.1 Redis 简介
  • Redis 概念

Redis 是一个速度很快的 非关系型数据库 ,可以存储key-value 之间的映射,可以将存储在内存中的键值对数据 持久化到硬盘 ,可以使用 复制特性 来扩展读性能,可以使用 客户端分片 来扩展写性能

  • Redis 与其他数据库对比

数据库名称

类型

数据存储

查询类型

附件功能

Redis

使用内存存储 (in-memory) 非关系型数据库

字符串、列表、集合、散列、有序集合

每种数据类型都有自己的专属命令,另外还有批量操作和不完成的事务支持

发布订阅、主从复制、持久化、脚本

memcached

使用内存存储的键值缓存

键值对之间的映射

创建、读取、更新、删除等命令

为提升性能而设的多线程服务器

MySQL

关系型数据库

数据库 - 表 - 行 结构

CURD 相关函数

支持 ACID 特性、主从复制、主主复制

postgresql

关系型数据库

同上

同上

同上

MongoDB

使用硬盘存储 (on-disk) 的非关系文档存储

数据库 - 表 -BSON 文档 结构

创建、读取、更新、删除等命令

支持 map-reduce 操作、主从复制、分片、空间索引

  • 附加特性
  • RDB 和 AOF 两种持久化方式
  • 支持主从复制

①执行复制的从服务器

1.2 Redis 数据结构

  • 字符串 string

set hello world
get hello
del hello

  • 列表 list

rpush list-key item
lpush list-key item2
lrange list-key 0 -1
lindex list-key 1
lpop list-key
rpop list-key

  • 集合 set

列表可以存储多个相同字符串,集合存储的字符串各不相同
sadd set-key item 添加成功返回 1,已经存在返回 0
smembers set-key
sismember set-key item 已经存在返回 1,不存在返回 0
srem set-key item

  • 散列 hash

可以将 hash 看做关系型数据库的
hset hash-key sub-key1 value1
hgetall hash-key
hdel hash-key sub-key1
hget hash-key sub-key1

  • 有序集合 zset
  • 有序集合和散列,都可以存储 键值对
  • 有序集合中,键:成员,值:分值,分值必须为浮点数
  • Redis 中唯一一个,既可以根据成员访问元素,又可以根据分值以及分值的排列顺序 访问元素的结构
    zadd zset-key 123 member1
    zrange zset-key 0 -1 withscores
    zrangeby zset-key 0 800 withscores 根据分值的范围查找
    zrem zset-key member1
1.3 Redis 案列分析(类 stackoverflow)
1.3.1 对文章进行投票
  • 业务分析
  1. 可以对文章进行点赞
  2. 文章评分:得票数 * 常量 + 文章发布时间
  3. 每人每篇只能投一次,只能投一周
  • 数据构建设计
  1. hash 文章信息(标题、网址、发布用户、发布时间、投票数)
  2. zset 文章发布时间(文章 ID、发布时间)- 可以通过发布时间排序
  3. zset 文章评分(文章 ID、评分)- 可以通过评分排序
  4. set 文章已投用户列表(key- 文章 ID、value- 已投用户 ID)- 一周后就可删除
  • 实现逻辑
  1. 当用户尝试对一篇文章投票,先去文章发布时间的 zset 中 (zscore 命令) 检查文章是否超过一周
  2. 如果文章仍然可以投票,zadd 将用户添加到文章已投用户列表 set 中
  3. 如果添加成功,则表示该用户第一次对该文章投票,并 (zincrby 命令) 为文章评分 zset 添加 400(设置的常量),并 (hincrby 命令) 为文章信息 hash 中投票数 +1
  • 代码展示 python
’‘’这里应该使用 Redis 事务,后续章节再添加进来‘’‘ONE_WEEK_IN_SECONDS = 7 * 86400
VOTE_SCORE  = 400

def article_vote(conn,uer,article):
    cutoff = time.time() - ONE_WEEK_IN_SECONDS
    if conn.zscore('time:'+ article)< cutoff
        return
    # - 1 的好处是无论前面添加了栏目,ID 的索引 -1    
    article_id = article.partition(':')[-1]
    if conn.sadd('voted:' + article_id,user)
        conn.zincrby('score:',article,VOTE_SCORE)
        conn.hincrby(article,'votes',1)
1.3.2 发布文章
  • 实现逻辑
  1. 首先创建一个文章 ID,可以通过计数器(INCR 命令)
  2. 将文章作者 ID 添加 (SADD 命令) 到文章已投用户列表,本人默认已经投了自己的文章
  3. 为文章已投用户列表的 set 设置 (EXPIRE 命令) 过期时间,1 周后自动删除
  4. 存储 (HMSET) 文章相关信息
  5. 将初始评分和发布时间分别添加 (ZADD) 到对应的有序集合中
  • 代码展示 Python
def post_article(conn,user,title,link):
    article_id = str(conn.incr('article:'))
    voted = 'voted:' + article_id
    conn.sadd(voted,user)
    conn.expire(voted,ONE_WEEK_IN_SECONDS)
    
    now = time.time()
    article = 'article:' + article_id
    conn.hmset(article,{
        'title':title,
        'link':link,
        'poster':user,
        'time':now,
        'votes':1  
    })
    conn.zadd('time:',article,now)
    conn.zadd('score:',article,now + VOTE_SCORE)
1.3.3 获取文章(评分最高的文章、最新发布的文章)
  • 实现逻辑
  1. 先使用 ZREVRANGE(倒序范围取值)在 zset 中取出多个文章 ID
  2. 然后在 hash 中对每篇文章 ID 执行 HGETALL 取出文章详细信息
  • 代码实现 Python
ARTICLES_PER_PAGE = 25
def get_articles(conn,page,order='score:'):
    start = (page-1) * ARTICLES_PER_PAGE
    end  = start + ARTICLES_PER_PAGE -1
    ids  = conn.zrevrange(order,start,end)
    articles = []
    for id in ids:
        article_data = conn.hgetall(id)
        # 给源数据添加 ID
        article_data['id'] = id 
        articles.append(article_data)
    return articles
1.3.3 对文章进行分组(分类,标签等类似功能), 并取出分组中评分最高或时间最新文章
  • 实现逻辑
  1. 分组可使用集合 set
  2. 将分组集合 set、评分有序集合 zset(或者时间的有序集合 zset),进行交集 (ZINTERSTORE 命令) 计算,存储到一个有序集合
  3. 然后从有序集合中获取排序的文章信息,为了减少 Redis 计算量,将交集结果缓存 60 秒
  • 代码实现 Python
def get_group_articles(conn,group,page,order='score:'):
    #交集的 key
    key = order + group 
    if not conn.exists(key):
        conn.zinterstore(key,['group:'+group,order],aggregate='max')
        conn.expire(key,60)
    #调用原有方法获取文章排序    
    return get_articles(conn,page,key)    

正文完
 0