1、redis实现投票:
- 使用hash存储一篇文章的信息(存储实体对象信息)
- 使用incr生成自增id
- 使用zset来保存排序列表、根据index进行分页
- 使用文章id作为member、根据业务规则计算score
- 使用set来分组
2、redis管理集群应用服务器的session会话:
- Cookie会话:所有http认证机制,都会使用Cookie来作为每次request的认证信息存储,即用Cookie实现session。
- 两种Cookie:
- 签名Cookie(signed):
- 包含用户信息和签名(signature)。签名,使用md5信息摘要的机制,来验证是否被篡改。
- 令牌Cookie(token)
- 使用一串随机字节走位token,服务器根据token在数据库中找到相关用户信息。
- 两种方式优缺点:
- token Cookie体积小,节省带宽。但占用服务器存储。并且对数据库访问性能要求高。
- 签名Cookie,体积大,验证签名机制费力、存在安全漏洞
- 签名Cookie(signed):
3、redis实现购物车:
- 不再在Cookie中保存信息。
- 而是保存在redis中:
- 以用户token为key,以当前用户购物车中的商品及其数量构成的hash【抽象为一个购物车】为value,作为redis键值对来实现
4、网页缓存:??怎么结合SpringMVC,实现网页缓存
- 将request和返回的content作为redis 字符串key-value进行缓存。
- 需要筛选可缓存的请求。
- 设置过期时间expire
5、数据行缓存:
- 是指:将数据行序列化为json,以行ID为key,作为字符串key-value缓存
- 数据行更新机制:
- 两个有序集合:
- 调度(schedule):member为行ID,score为时间戳,记录下一次执行缓存的时间
- 因为根据时间戳排序,每次从队首获取要当前要缓存的行ID。
- 延时(delay):member为行ID,score为时间间隔,记录delay值,用于控制缓存频率(是否缓存、下一次什么时间缓存)
- 可以设定delay<=0,则删除缓存,不再调度。
- 其实delay集合可以用hash实现吧?
- 调度(schedule):member为行ID,score为时间戳,记录下一次执行缓存的时间
- 一个守护进程负责相关工作的运行【类似引擎】
- 两个有序集合:
6、网页分析:
- 决策哪些商品应该进行redis缓存优化:比如,设置一个记录商品浏览次数的zset,浏览一次则该商品score -1。这样,获得一个商品热度排行榜
redis 构建twitter后端
1、redis建模:
- 用户信息(user hash):
- 【user:${userId} hash】用户信息hash
- 【user:id: string】用户信息id自增计数器
- 敏感信息不保存在此处。(密码、邮箱等)
- 【users: hash】用户名login.lower()作为key-value的已注册用户信息hash
- 可用于检查用户名是否已被注册
- 【user:${userId} hash】用户信息hash
- 状态信息(status hash)(即说说、动态)
- 【status:${statusId} hash】状态信息hash。。。类似的实体对象信息hash,都有相应的id自增计数器
- 时间线( timeline):
- 主页时间线(home timeline)
- 【home:${userId}=statusId~timestamp zset】用户的主页时间线
- 由自己和following 的用户,以及只能推荐的用户发表的status组成。
- 个人时间线(profile timeline)
- 主页时间线(home timeline)
- 关注列表
- 关注者列表(followers list)
- 【followers:${userId}=userId~timestamp zset】关注当前用户的人列表。。。timestamp是关注的时间
- 关注者列表(followers list)
- 正在关注列表(following list)
- 【following:${userId}=userId~timestamp zset】当前用户正在关注的人列表
2、关注、取关
- 修改关注列表:followers zset、following zset
- 修改user hash中followersCount、followingCount这些统计信息
- 将被关注者(取关者)的profile timeline中的若干最新状态信息,加入到关注者的home timeline中。
- 注意,用户的home timeline,应该保留最新的HOME_TIMELINE_SIZE数量的status。而不应无限追加。
3、status发布
- 发布status后更新followers的home timeline的方式分两种:
- followers较少时(1000以内):
- 直接更新所有followers的home timeline
- 较多时:
- 使用【延迟任务】推送给所有followers
- followers较少时(1000以内):
- 关注度的二八原则:
- followers超过1000的只占很少一部分。
4、twitter类社交网站,其他常见特性:
- 私人用户。关注这类用户,需要审批机制
- 收藏
- 用户间私聊
- 评论、点赞、转发
- @用户。。。#话题
- 投诉机制
- 用户分组
5、流API——不知所云
- 一般流式API指的是链式编程,即chain。而此处指的是stream。
- 社交网站的一些动作如发表状态、删除状态等,要了解网站的状态,就要为这些动作【广播事件】,然后由【事件监听器】监听处理这些事件。
- 本节通过redis的发布订阅(Publish/Subscribe)模式实现广播和监听
- 流式数据
- 使用http分块(chunked)传输,将消息用流(stream)的形式返回给订阅的客户端
6、注册新用户时,锁住用户名:
- 锁住当前用户名,保证注册过程中该用户名不再被别人抢注。如果获取锁失败,表示,该用户名已经被别人锁住,正在注册。
7、外键关联除了要有fk_id外,应该加上fk_name:
- 通常都需要展示关联的信息(最少是name)。
- 如果加上name,坏处是改name的时候,需要大规模关联修改。好处是不用每次关联查询。
- 但是,由于查询概率远大于修改概率,所以应该带上name
1、自动补全(autocomplete):
- 常见应用场景:根据输入前缀,自动补全搜索热词
- 使用zset以及ZRANGEBYLEX命令实现:
- 向zset中添加元素来创建查找范围,获取范围内的元素后再移除添加的元素
- 根据输入的prefix,获取在当前编码(通常使用utf-8)下的前驱(predecessor)、后继(successor)
- 如果是utf-8的话,前驱的计算方式,是prefix---转为utf8编码,然后最后一个字节减1
- 后继则直接为prefix+\xef\xbf\xbf【\uffff Unicode字符的utf-8字节形式】
- 将predecessor、successor插入zset,然后使用ZRANGEBYLEX来获取两者之间的元素【注意使用(开区间,从而去掉两端】——详细用法参考Redis命令参考文档
- 最后使用ZREM移除predecessor、successor
- 根据输入的prefix,获取在当前编码(通常使用utf-8)下的前驱(predecessor)、后继(successor)
- 设置zset所有score为0,以便直接对member进行排序搜索
- 向zset中添加元素来创建查找范围,获取范围内的元素后再移除添加的元素
- 要在redis-cli命令行,添加字节(Redis string的最小单位),必须在引号内使用\x加两位16进制。
- 竞争条件 race condition:是共享数据保持一致性而加锁机制中的概念
- 在合理的范围内,将部分计算转移到客户端,以【分布式计算】的思维,来减轻服务器的负载。
2、文件分发:
- 常见三种文件分发方式:
- NFS或者Samba:用于服务器持续分发文件
- Rsync软件:(见linux 远程复制)
- 使用同步增量的方式,减少传输量。
- 用于内容逐渐发生变化(比如日志文件)
- BitTorrent协议:
- 将文件分片(partial)分发到多台机器上,然后让他们互相分享自己拥有的数据,从而降低服务器的负载。
- 用于将文件副本分发到多台机器
- 局限:
- 都有显著的安装成本和相对价值
- 都有独立的服务,需要维护帐号和权限
- NFS/Samba在网络不稳定时会出问题
- Rsync虽然对网络连接不敏感,但是同步之前,必须首先下载整个文件
- BitTorrent,需要客户端有BitTorrent客户端软件做支撑。
- 日志分析:
- Map/Reduce、文件复制不适合
- 在本地进行数据聚合计算,减少Redis远程通信的资源消耗。
- 发送/接收/处理日志文件??
3、
使用redis记录日志:
- 类UNIX系统中常见的两种日志记录方式:
- 追加日志行到日志文件,随着时间推移添加新的日志文件(rolling)
- syslog服务。。
- 转发功能:接收其他程序的日志消息,转发到相应的日志文件
- 转发功能:接收其他程序的日志消息,转发到相应的日志文件
- 追加日志行到日志文件,随着时间推移添加新的日志文件(rolling)