简介

Redis作为重要的缓存数据库在高并发的解决方案中起着重要作用。为了系统的学习Redis,也为了秋招(美团比较关注Redis 的掌握),计划编写该系列博客,也是为了整理知识点。
本篇主要介绍了Redis的基础知识与原理。之后将更新Redis的分布式相关知识和实际使用会用到的操作。希望读完这三篇文章可以完全掌握Redis的使用!

NoSQL

Not Only SQL的简称。NoSQL是解决传统的RDBMS在应对某些问题时比较乏力而提出的。具体的表现如下:

  1. RDBMS依赖的表结构扩展性差,当表很多时,修改表结构的成本会很高;
  2. IO较慢:虽然引入了索引,但是还是会存在索引失效的问题;
  3. 海量数据处理乏力:由于1和2,导致了3。

关系型数据库和NoSQL数据库的关系从来都不是谁取代谁,而是在一个复杂的高并发系统中相互增益,共同为系统提供可用性。

主流分支

  1. KV数据库
  • Redis:KV主存数据库,所有的操作在主存中。并 定期异步地将数据进行持久化。但是数据库提供 性能会受主存大小的影响,主存成本高。
  1. 列族数据库 HBASE就是列族数据库,虽然没有改变传统的数据库结构,但是其对数据分析的支持会更好。
  • Cassandra:是Facebook的分布式数据库。其优点是 1)该数据库的设计模式非常灵活,不需要先 设计数据库模式,添加或删除字段非常方便;2)支持范围查询,即可以对键进行范围查询;3)高可扩展 性:单点故障不影响整个集群,支持线性扩展。
  • Hypertable:也是一个开源的分布式数据库,其使用的是bigtable。面向的是大规模的分布式集 群,比如HDFS和KFS。
  1. 文档数据库
    文档数据库并不关心高性能的读写并发,而是保证大数据的存储和良好的查询性能。
  • MongoDB:介于关系型数据库和 非关系型数据库之间,支持许多数据格式和高速访存。
  • CouchDB:支持JSON和AtomPub。为了确保数据一致性,CouchDB符合ACID属性。

Redis简介

Remote Dictionary Server的简称。特点是在主存中存储数据。主存的特点是:IO快,易失性,成本高
这个特点使得:

  • Redis不适合存储大文件;
  • 不适合存储需要持久化的文件;
  • 适合存储热点数据(要求快速IO);
  • 适合存储具有一定生命周期的数据(当生命周期结束就被销毁或者持久化到磁盘上)。

在Redis中, 数据的存储有两种格式:RDB和AOF。RDB记录的是真实的数据,AOF记录的对数据的操作,且在Redis中会对操作进行重写(对可以合并和简化的操作进行重写)。AOF的效率更好,但是RDB采用压缩存储,存储效率高。

Redis数据类型

Redis是KV数据库,所有的Key都是字符串且唯一,数据类型指的是value的类型。

redis java
string String
hash HashMap
list LinkedList
set HashSet
sorted_set TreeSet

Redis有16个数据库可以使用。默认使用的是0号数据库。使用select index的方式切换数据库。

key的命名规则

key的操作

1. 基本操作操作

在分布式的场景下,保证多个节点存储的key不冲突是一个很关键的点。

#删除
del key
# 获取
get key
# 模糊查询 ?表示一个占位符 *表示任意长度任意字符 []指定若干字符
keys pattern
#类型
type key
# 自增操作
incr key increment
incrbyfloat key increment

由于key是一个字符串,所以在进行操作时会转化成数值来进行计算。由于Redis是单线程的,命令的执行是先后顺序的,所以不用担心并发引发的数据一致性问题。

2. 设置生命周期

由于redis是采用主存存储,因此通常存储的是具有一定生命周期的数据。

# 设置生命周期
expire key seconds
pexpire key milliseconds
expireat key timestamp
pexpireat key milliseconds-timestamp# 获取生命周期
ttl key
pttl key #时间戳# 持久化
persist key

String类型

String类型是一种一对一的映射关系。

key value
name 咸鱼突刺
age 18

操作:

# 添加数据
set key value# 获取
get key# 删除
del key# 添加多个
mset key1 value1 key2 value2...# 获取多个
mget key1 key2 ...# 获取字符串长度
strlen key1# 在字符串后追加字符串
append key value

Hash类型

如果我们需要一个key对应多个value时就需要使用hash结构。相当于在string的基础上嵌套了多个结构。Hash的value 中只能存储字符串,且每个键值对的存储上限是 2^32 -1。

如果filed数据较少,底层的存储结构采用数组的方式,如果较多采用HashMap的形式。

# 新增数据
hset key field value
hmset key field1 value1 field2 value2...
hsetnx key field value# 获取数据
hget key field
hgetall key
hkeys key
hvals key# 删除数据
hedel key field1 field2....# 获取字段的数量
hlen key# 判断是否存在
hexists key field

list类型

list是序列结构,即各个元素之间有位置上的关系。redis中的list实现是 双向链表,逻辑结构为队列。根据队列的特点,不难猜出对list的操作应该包括在双端的操作。key相当于是一个指针。

# 添加数据
lpush key value1 value2
rpush key value1 value2# 获取数据
lrange key start stop# 获取指定位置的value
lindex key index# 获取长度
llen key# 获取并移除
lpop key
lpop key# 规定时间内获取并移除数据
blpop key1 [key2] timeout
brpop key1 [key2] timeout# 移除指定数据
lrem key count value

set类型

set的定位和数学中的集合一致。set的查询效率高,且可以存大量的 数据。其存储结构和Hash结构完全 一致,但是其value的值为空。

常用来解决:

  • 数据的快速过滤和查找;
  • 存储用户的权限等对顺序没有要求的内容。
# 添加数据
sadd key member1 [member2]# 获取全部数据
smembers key# 删除数据
srem key member1 [member2]# 获取数据量
scard key
# 是否包含某个member
sismember key member# 随机获取指定数量的数据
srandmember key [count]# 随机获取一个数据并移除
spop key# 集合运算
sinter key1 [key2]
sunion key1 [key2]
sdiff key1 [key2]# 集合运算并保存结果
sinterstore destSet key1 [key2]
sunionstore destSet key1 [key2]
sdiffstore destSet key1 [key2]# 将指定数据从原始集合移动到目标集合
smove source dest member

zset类型

是一种有序的数据结构。score就是判断的规则。sorted_set在set的基础上加入了一个score字段,按照这个字段排序。

# 添加数据
zadd key score1 member1 [score2 member2]# 获取全部数据
zrange key start end [withscore]
zrevrange key start end [withscore]# 删除数据
zrem key member# 按条件查找数据 limit指定是个数
zrangebyscore key min max [withscore] [limit]
zrevrangebyscore key max min [withscore] [limit]# 获取数据对应的索引
zrank key member
zrevrank key member# 获取score值
zscore key member
zincrby key increment memeber# 按照条件删除数据
zremrangebyrank key start end
zremreangebyscore key min max# 获取集合总量
zcard key
zcount key min max# 集合操作:交集会将key相同的score相加
zinterstore destSet numkeys key1 [key2]
zunionstore destSet numkeys key1 [key2]

Redis的持久化

持久化就将数据存储在本地磁盘,为了数据的恢复。通常的方式有:AOF和RDB。


RDB详解

开启RDB的指令有两种:

  • save指令 ,一旦执行,CPU会立刻去对数据进行持久化 ,但是由于Redis是单线程的,当数据量很大,会导致长时间的阻塞
  • bgsave指令,一旦执行Redis会在CPU空闲时执行持久化 操作。

RDB配置

AOF(Append Only File)

记录的是对数据的操作。读操作不用记录,修改操作记录。 AOF之所以效率高,是因为其采用指令重新写机制,将可以合并且简化得到指令重写,大大减少了文件体积。比如用户的单个插入会被整合成mset的形式。

AOF三种写策略:

  • always:每次发生变化就写一次,效率低

  • everysec:每秒将缓冲区的指令同步到缓冲区,准确率高,性能好。

  • no:系统控制,不建议使用。

AOF功能开启

# 开启AOF
appendonly yes|no# AOF写数据策略
appendfsync always|everysec|no# 日志文件名
appendfilename filename
# 地址
dir path

AOF重写

AOF重写是为了压缩AOF文件的大小。通过指令重拍和组合来减少不必要的操作。

  • 手动重写

    bgrewriteaof
    
  • 自动重写
    auto-aof-rewrite-min-size size
    auto-aof-rewrite-min-percentage percentage
    

AOF与RDB的比较

持久化方式 RDB AOF
占用空间 小(数据压缩) 大(指令重写)
存储速度
恢复速度
资源消耗
启动优先级

Redis事务

# 开始事务,之后的所有指令都是属于该事务的
multi# 取消事务
discard#执行事务
exec

Redis锁

为了在事务过程中保持数据的操作不出错,redis中引入了锁的概念。这个锁就是设置一个string,对某个字段column设 锁就是setnx lock-column value,这个value设置的就是我们操作的数值,每个业务进入之后就对这个value进行修改。
同时还需要配合expire防止程序卡死导致锁无法释放。
注意:Redis中setnx操作是原子性操作。

# 监听key
watch key1 key2..
# 取消监听
unwatch

Redis删除策略

Redis所占内存成本太高,要求定期移过期数据,以缓解内存的压力。有以下几种删除策略。

  • 定时删除:设置一个定时器,对过期的数据定期清洗。虽然可以保证内存中没有过期的数据 ,但是会对CPU造成巨大压力。

  • 惰性删除:当我们使用一个数据的时候再去判断是否过期。这样虽然减少了CPU的压力但是会造成数据的堆积,加重了内存的压力。

  • 定期删除:让CPU定期删除是一个折中策略。通过配置信息指定定期删除的条件(是一种随机抽检的方式)。 使用较多。

Redis的逐出策略

redis在存储数据时,会先调用freeMemoryNeeded()函数检测内存是否充足。当内存已满,且无法清出足够的空间存放新的 数据就会使用数据逐出,其实这和OS中的页面交换算法思想一致。选择用处最小的数据放出。

相关配置

# 最大可用内存
maxmemory# 每次选择待删除的据个数
maxmemory-samples# 删除策略
maxmemory-policy策略有:1. lru:最近最少使用的数据淘汰2. lfu:使用次数最少的数据淘汰3. ttl:快过期的数据淘汰4. random:随机挑选数据淘汰检测范围:5. 检测易失性数据:volatile-xxx eg:volatile-lru6. 检测全库数据:allkeys-xxx7. 放弃使用数据驱逐:no-envitction

高并发解决方案——Redis(一)相关推荐

  1. Java 高并发_JAVA并发编程与高并发解决方案 JAVA高并发项目实战课程 没有项目经验的朋友不要错过!...

    JAVA并发编程与高并发解决方案 JAVA高并发项目实战课程 没有项目经验的朋友不要错过! 1.JPG (37.82 KB, 下载次数: 0) 2018-12-3 09:40 上传 2.JPG (28 ...

  2. 打车业务下单高并发解决方案

    简介: 打车业务下单高并发解决方案 前言 在技术领域有一条准则,即不存在银弹技术.在实际工作中,通常无法通过几项简单的技术组合就解决实际业务中各种场景下的复杂问题.虽然追求架构的简单简洁也是架构师的目 ...

  3. 高并发解决方案 超详细!!!

    高并发解决方案 1. 高并发和大流量解决方案 高并发解决方案案例 流量优化:防盗链处理 前端优化:减少HTTP请求,合并css或js,添加异步请求,启用浏览器缓存和文件压缩,CDN加速,建立独立图片服 ...

  4. 高并发编程(四)高并发解决方案从前端到数据库

    1. 高并发和大流量解决方案 高并发架构相关概念 并发:在操作系统中,是指一个时间段中有几个程序都处于已启动运行到运行完毕之间,且这几个程序都是在同一个处理机上运行,但任一个时刻点上只有一个程序在处理 ...

  5. JavaWeb 并发编程 与 高并发解决方案

    在这里写写我学习到和自己所理解的 Java高并发编程和高并发解决方案.现在在各大互联网公司中,随着日益增长的互联网服务需求,高并发处理已经是一个非常常见的问题,在这篇文章里面我们重点讨论两个方面的问题 ...

  6. 搞懂分布式技术30:高并发解决方案——提升高并发量服务器性能解决思路

    高并发解决方案--提升高并发量服务器性能解决思路 一个小型的网站,可以使用最简单的html静态页面就实现了,配合一些图片达到美化效果,所有的页面均存放在一个目录下,这样的网站对系统架构.性能的要求都很 ...

  7. 大型网站应用之海量数据和高并发解决方案

    一.网站应用背景 开发一个网站的应用程序,当用户规模比较小的时候,使用简单的:一台应用服务器+一台数据库服务器+一台文件服务器,这样的话完全可以解决一部分问题,也可以通过堆硬件的方式来提高网站应用的访 ...

  8. 电商中常见的高并发解决方案

    目录 多级缓存 什么叫多级缓存 多级缓存的实现思路 Redis 缓存同步 MySql 数据 Nginx 限流 什么是限流 常见的限流算法之漏桶算法 nginx 限流的方式 控制速率 控制并发量(连接数 ...

  9. Token高并发解决方案

    Token高并发解决方案 一:作为token使用的第三方 客户端模式使用token 可以采用单例模式或定义一个全局变量isRefresh 标志,加同步锁Synchronized来保证token过期的那 ...

最新文章

  1. 《构建之法》问题与思考
  2. 甲骨文称 Java 序列化的存在是个错误,计划删除
  3. AGC026E - Synchronized Subsequence
  4. 记录 Parameter with that position [1] did not exist; nested exception is java.lang.IllegalArgumentExce
  5. 无法安装软件之解决其一 (windows installer服务篇)
  6. python三维模型_python三维模型
  7. 金牌访谈栏目《架构师说》重磅上线!
  8. 电脑连上网,可是软件、谷歌等浏览器都显示未连接到互联网。远程计算机设备将不受连接,两个解决方法。
  9. c语言开发谷歌浏览器插件,用Chrome学编程
  10. 安装wsl kali 遇到WslRegisterDistribution failed with error: 0x80070057 Error: 0x80070057解决
  11. [深入理解Android卷二 全文-第四章]深入理解PackageManagerService
  12. IOS屏幕旋转的检测 与 强行切换
  13. 2.4G功放芯片,支持国产
  14. Java 集合转数组的toArray()和toArray(T[] a)方法通俗易懂
  15. 个推和极光推送技术介绍
  16. php files 转数组,转 PHP文件上传$_FILES数组各键值含义说明
  17. Win 10生态圈:高度智能化的人造大世界
  18. CUDA Installer 前面的 X
  19. 潘多拉盒子 使用 hd-idle 硬盘休眠设置
  20. 利用excel与notepad++采集京东热门图书榜的清单

热门文章

  1. 兆骑科创创新创业大赛活动举办,线上直播路演,投融资对接
  2. npm配置vue-cli所遇EACCES权限问题及解决方案
  3. 粉丝看了教程成功发文章了,恭喜一下,并说下近期计划
  4. 初学者如何学习一门新的计算机语言!!!
  5. python定义一个student类、有下面的_Python的类和方法——成员可见性
  6. 局域网访问文件提示服务器内存不足,“服务器存储空间不足”的问题
  7. 有没有Type-C接口的无线投屏器?HDMI、USB、Type-C接口的无线投屏器又有什么区别呢?
  8. 开封抖音广告如何有效投放?
  9. php中的乐观锁和悲观锁
  10. cad调了比例因子没反应_为什么你总混淆各种CAD命令?