[DB] Redis
为什么用Redis
- 是什么
- 一个小程序
- 缓存 & 数据库
- 单线程worker
- 新版本:IO threads
- epoll:多路复用
- 与Memcache区别
- 支持持久化:RDB快照、AOF日志
- 丰富的数据类型
- 速度
- 硬盘:寻址时间ms,带宽(吞吐)百兆~G/s(固态硬盘pci-e nvme)
- 内存:寻址时间ns,比硬盘快10w倍
- 文件
- 全量扫描(高IO),过大(T级)时,查询会变慢
- 数据库
- 对数据进行规划,分页存储
- 为1kb的数组建立索引,若将数组分成4bit的数据块,索引大小为1byte
- 索引大小可设置,窗口越小,索引越大
- 索引也是数据,存在磁盘中
- B+树,树干在内存,索引磁盘
- datapage->索引->B+树
- 读取数据:先扫描B+树,读取相应索引到内存扫描,再读取相应datapage到内存扫描
- 表很大时,增删改(写)查(读)中,写操作会变慢
- 读操作单线程不受影响,但并发很大或查询复杂时会受影响(分布式、微服务解决并发问题)

- 把数据全部放到内存,且支持sql查询
- SAP HANA:关系型数据库(内存中运行),内存2T(erp+hana+2T服务器=¥2E)
- 数据在内存中比在硬盘中小:如有1000个user对象,住址字段是“Beijing”,JVM中只有一个“Beijing”字段,但序列化到磁盘后有1000个(内存指针实现了数据复用)
- 公司全部数据存在哪?
- 折中方案:将全量数据中频繁使用的数据放到内存中,其他放在硬盘数据库中
- 内存型数据库:redis、memcache
- 为什么是key-value型?内存中只有部分数据,无法按SQL的范式进行设计(空间换时间)
- 关系型数据库中的约束(范式)设计减少了数据冗余
- key-value的使用者只需关注每条记录自身,而不需查看其他记录
- worker 单线程,6.x io threads 多线程(多线程读取,单线程处理)
- Value类型:String、list、set、hash,每种类型有自己的本地方法
- 先用json把所有对象序列化为字符串,再存到memcache
事务
- 不是真正的事务,是一种模拟
- 本质:将一组操作放入队列中,一次执行(批处理)
- Oracle中事物的本质:将事务的DML操作写入日志

锁
- 执行事务操作时,如果监视的值发生了变化,则提交失败
- exec后,返回(nil),表示提交失败
消息
- 消息类型
- Queue:队列,点对点
- Topic:主题,广播 / 群发
- 常用消息系统
- Redis:只支持Topic
- Kafka:只支持Topic,需要Zookeeper支持
- JMS(Java Messaging Service):支持Queue和Topic
- Reids消息机制
- publish:发布消息
- subscribe:订阅消息
- psubscribe:使用通配符来订阅消息
持久化
- 本质上是一种备份和恢复
- RDB:默认
- 可看成一种快照,每隔一段时间将内存中数据保存到硬盘(dump.rdb)
- 配置参数:redis.conf
- 优点:恢复快
- 缺点:两次RDB之间,可能发生数据丢失
- AOF:记录日志(append only file)
- 配置参数
- appendonly yes
- bin/redis-server conf/redis.conf
- 日志重写
- 将过程日志改为最终状态记录(最终一致性),减小日志文件占用空间
- 使用压力测试模拟,模拟10万次操作,可观察到日志文件先变大后变小
- bin/redis-benchmark -n 100000

- 参数设置
- no-appendfsync-on-rewrite no :执行重写的时候,不写入新的日志
- auto-aof-rewrite-percentage 100 :当AOF文件比上次的大小超过了100%,执行重写
- auto-aof-rewrite-min-size 64mb :当AOF日志文件达到了64M,执行重写
- RDB和AOF同时存在时,优先读取AOF进行恢复(持久性保证更好)
主从复制
- 主从复制集群
- 作用
- 主从复制,主从备份,防止主节点宕机
- 任务分离,分摊主节点压力(如朋友圈读比写压力大很多)
- 读写分离,主节点写入,从节点读取
- 架构
- 星型模型:效率较高,HA复杂
- 线型模型:效率较低,HA简单
- 作用

- 分片
- 使用第三方软件Twemproxy实现负载均衡
- Twemproxy作为代理接收来自多个程序的访问,按照路由规则转发给Redis服务器再返回


- 配置
- 主节点
- 关闭RDB和AOF(任务分离)
- bind 0.0.0.0(允许所有网段IP连接)
- 查看主从关系:info replication
- 从节点
- replicaof localhost 6379
- 开启rdb和aof
- bin/redis-cli -p 6380
- 默认从节点只读
- 第一次同步RDB(较大),后面同步AOF
- 一次不要启动太多从节点
- 主节点

HA(哨兵)
- 2.4后开始有
- 配置文件:sentinel.conf



- +try-failover master mymaster 192.168.174.111 6379
- switch-master mymaster 192.168.174.111 6379 127.0.0.1 6381
- +slave slave 127.0.0.1:6380 127.0.0.1 6380 @ mymaster 127.0.0.1 6381
原理
- memcache和redis:都是k-v,但redis的value有类型,以及基于类型的方法
- memcache的k,v都是string类型,数据向计算移动
- redis实现了计算向数据移动,减少IO量

安装
- 在Redis官网进入下载页面,复制下载链接
- 进入linux命令行,创建目录
- wget 下载链接
- tar xf 压缩包文件
- 进入redis目录
- vi READMI.md
- make:编译源码
- make PREFIX=安装路径 install:安装
- yum install gcc -y:安装gcc(如果没有的话)
- make distclean:清理
- vi ~/.bash_profile:添加环境变量
- REDIS_HOME=/root/training/redis-5.0.8
- export REDIS_HOME
- PATH=$REDIS_HOME/bin:$PATH
- export PATH
- source /etc/profile:环境变量生效
- cd utils
- sudo ./install_server.sh:开启服务,设置端口号,配置文件,日志文件,持久化目录
- service redis_6379 status:查看redis进程状态
- ps -fe | grep redis:查看所有redis进程状态
- 核心配置文件:redis.conf(从安装文件拷贝到安装目录)
- 设置后台运行:daemonize no


- strace -ff -o ~/stracedir/ooxx ./redis-server:追踪线程文件

- cd /proc/task/8625

- cd /proc/8625/fd

- redis-cli
- >bgsave:记录日志
- 业务处理是单线程的
- 一个线程如何处理多个客户端请求
- BIO->NIO->epoll(多路复用)
- yum install man man-pages
- fcntl(可设置非阻塞)
- 用户很多时(如1000个),轮询的代价太大(用户态 / 内核态切换1000次)
- select(多路复用,同步非阻塞,用户态 / 内核态切换1次,拷贝1000个fd到内核,内核遍历1000次,然后告诉redis需要读哪个用户)
- 缺点在于redis->kernel传参太多,且内核遍历次数太多
- 多路复用器:在内核中,如select、poll、epoll,告诉redis有没有数据到达,再由redis自己去读取
- 单线程不足:只能工作在一个CPU上,不能发挥硬件资源
- IO thread 事务性:保证一个client的一个connection中发送的指令是有顺序的
- 不需使用分布式锁/事务
- 类似:kafka k,v 消息构建
- 6.x之后,io threads多线程(io读写),无论哪个版本,工作线程就一个




使用
- 方法一
- redis-cli
- 方法二
- nc localhost 6379
- 方法三
- exec 8<> /dev/tcp/localhost/6379
- echo -e 'keys *' >& 8
- cat <& 8
- 常用命令
- flushall:清除所有内容
- help @String:查看String的使用方法
- 5种value类型
- String
- 字符串
- strlen:字节个数
- 二进制安全:客户端根据自身编码方式发送byte数组
- hbase、zookeeper、kafka
- 数值
- incr
- decr
- 单线程原子
- 秒杀限流
- 二进制bitmap
- setbit k1 1 1
- 从左向右,自动扩容
- 场景1:统计用户任意时间窗口内登录几次(如一年内)
- setbit sean 3 1:sean在第4天登录了
- setbit sean 364 1:sean在第365天登录了
- bitcount sean 0 -1:统计一共登录了几次
- strlen sean:用了多大空间
- 场景2:统计一段时间内有多少人登录
- setbit 20200101 7 1
- setbit 20200101 3 1
- setbit 20200102 3 1
- bitop or res 20200101 20200102
- bitcount res 0 -1

- list
- 模拟栈、队列、数组
- 操作
- lpush k1 a b c d:左侧插入数据
- lrange k1 0 -1:查看范围内元素
- rpush k1 x y z:右侧插入数据
- ltrim k1 0 -1:删除区间之外的元素
- hash
- 场景:详情页 / 聚合,数据来自不同的库
- set
- 无序,去重
- 操作
- sadd k1 ooxx xxoo oxox ooxx:添加元素
- smembers k1:显示元素
- srandmember k1 3:不重复地取出3个元素
- srandmember k1 -8:可重复地取出8个元素
- sunion k1 k2:k1 k2 并集
- sinter k1 k2:k1 k2 交集
- sdiff k1 k2:
- 场景
- 随机事件:抽奖
- 集合运算:单线程串行,成本较大,通常会独立到一个redis实例
- sorted_set
- 有序,去重,动态维护顺序,底层是跳表(skiplist)
- 操作
- zadd k1 3.1 apple 2.5 orange 7 banana:插入数据
- zrange k1 0 -1 withscores:按分值排序
- zrange k1 0 1:取出前两名
- 场景
- 排行榜
- 动态翻页

参考
数据库知识网站
redis主从设置
https://blog.csdn.net/qq_24113267/article/details/79150533
[DB] Redis的更多相关文章
- 分布式锁三种实现方式(DB,redis,zookeeper)比较
先贴出看到的一篇博客,后续补充自己总结分析的. https://blog.csdn.net/u010963948/article/details/79006572
- Redis与DB的数据一致性解决方案(史上最全)
文章很长,而且持续更新,建议收藏起来,慢慢读! 高并发 发烧友社群:疯狂创客圈(总入口) 奉上以下珍贵的学习资源: 疯狂创客圈 经典图书 : 极致经典 + 社群大片好评 < Java 高并发 三 ...
- redis大幅性能提升之使用管道(PipeLine)和批量(Batch)操作
前段时间在做用户画像的时候,遇到了这样的一个问题,记录某一个商品的用户购买群,刚好这种需求就可以用到Redis中的Set,key作为productID,value 就是具体的customerid集合, ...
- Basic Tutorials of Redis(2) - String
This post is mainly about how to use the commands to handle the Strings of Redis.And I will show you ...
- Redis连接
using System; using System.Configuration; using StackExchange.Redis; namespace Redis { public sealed ...
- Redis到底该如何利用(三)?
上两篇受益匪浅,秉着趁热打铁,不挖到最深不罢休的精神,我决定追加这篇.上一篇里最后我有提到实现分级缓存管理应该是个可行的方案,因此今天特别实践了一下.不过缓存分级之后也发现了一些问题,例如下图: 当a ...
- Redis 数据库入门指南
Redis 是一个开源数据库,它使用内存数据结构存储,可作为数据库.缓存和消息代理使用.Redis 支持丰富的数据结构,有:字符串(Strings).哈希(Hashs).列表(Lists).集合(Se ...
- redis——学习之路五(简单的C#使用redis)
redis官方推荐使用的客户端程序 打星星表示推荐使用的客户端程序,一个笑脸表示最近6个月内有过正式活动的.http://redis.io/clients/#c 从这里我们可以判断官方推荐我们使用Se ...
- Redis 详解 (一) StackExchange.Redis Client
这期我们来看StackExchange.Redis,这是redis 的.net客户端之一.Redis是一个开源的内存数据存储,可以用来做数据库,缓存或者消息代理服务.目前有不少人在使用ServiceS ...
随机推荐
- CMS前世今生
CMS一直是面试中的常考点,今天我们用通俗易懂的语言简单介绍下. 垃圾回收器为什么要分区分代? 如上图:JVM虚拟机将堆内存区域分代了,先生代是朝生夕死的区域,老年代是老不死的区域,不同的年代对象有不 ...
- 第四单元总结&期末总结
OO第四单元总结&期末总结 一.第四单元总结 第一次作业 在第四单元的作业中,我的架构是逐步演进的.设计第一次作业的架构时并没有考虑到后续作业会增加新的图,所以直接把类图的实现放在UmlInt ...
- 对象存储服务MinIO安装部署分布式及Spring Boot项目实现文件上传下载
目录 一.MinIO快速入门 1. MinIO简介 2. CentOS7更换成阿里云镜像 3. 安装 3.1 下载 3.2 运行测试 4. 配置脚本执行文件 4.1 创建配置执行文件 4.2 执行 二 ...
- 【Azure 环境】在Windows系统中 使用Terraform创建中国区Azure资源步骤(入门级)
Terraform(全称:Hashicorp Terraform )是一种开源工具,用于预配和管理云基础结构. 它将基础结构编入描述云资源拓扑的配置文件中. 这些资源包括虚拟机.存储帐户和网络接口等. ...
- SHA256sum系列命令检测文件完整性
1 sha256sum sha256sum是一个检测文件完整性的命令,一般下载的文件都会附带一个哈希值,使用sha256sum计算下载文件的哈希值再与目标哈希值比较即可确定文件是否完整,类似的命令还有 ...
- shell脚本 3 流程控制
shell流程控制 流程控制是改变程序运行顺序的指令.linux shell有一套自己的流程控制语句,其中包括条件语句(if),循环语句(for,while),选择语句(case).下面我将通过例子介 ...
- linux-shell 识别当前所使用的shell
echo $SHELL 或者 echo $0
- 玉帝传美猴王上天,大闹天宫之Java设计模式:命令模式
目录 示例 改进代码 命令模式 定义 意图 主要解决问题 何时使用 优缺点 玉帝传美猴王上天 命令模式和策略模式的区别 示例 系统需要设计一个命令行界面,用户可输入命令来执行某项功能,系统的功能会不断 ...
- python进阶(16)深入了解GIL锁(最详细)
前言 python的使用者都知道Cpython解释器有一个弊端,真正执行时同一时间只会有一个线程执行,这是由于设计者当初设计的一个缺陷,里面有个叫GIL锁的,但他到底是什么?我们只知道因为他导致pyt ...
- JAVAEE_Servlet_16_HttpServletRequest中常用方法(三)
HttpServletRequest中常用方法(三) * 回顾ServletContext对象,ServletContext对象是Servlet上下文对象 - 创建ServletContext对象 S ...