1. 单体时代
但随着数据量的急剧增加,应用服务器会出现CPU及内存压力问题,数据库服务会出现IO压力。
2. 解决CPU及内存压力
此时,用户的请求被负载均衡平分之后分担给各个服务器。但是还是存在一个问题,那么就是session存在哪的问题。
3. 减少IO压力
由于我们会对数据库进行进行主从复制读写分离等操作,那么这虽然会提升一定的性能,但是会破坏一定的业务逻辑。因此,我们将最近频繁读取的数据存储在缓存数据库中,从而减少IO的读操作。
1. NoSQL数据库概述
NoSQL意思就是“不仅仅是SQL”,泛指非关系型数据库。NoSQL不依赖业务逻辑方式存储,而以简单的key-value模式存储,因此大大的增加了数据库的扩展能力。
2. NoSQL适用场景
3. NoSQL不适用场景
4. 常见的NoSQL数据库
1. 行式存储数据库
这里数据库存储的时候是按每行进行存储的,那么当我们查询某一个人的相关信息的时候,这就十分之快。如果我们查询所有人的年龄的平均值的时候就很慢。
2. 列式存储数据库
这里数据库存储的时候是按每列进行存储的,那么当我们查询某一个人的相关信息的时候,这就十分之慢。如果我们查询所有人的年龄的平均值的时候就很快。
1. 概述内容
key-value
存储系统。string
(字符串)、list
(链表)、set
(集合)、zset
(有序集合)和hash
(哈希类型)。push/pop、add/remove
及取交集并集和差集及更丰富的操作,而且这些操作都是原子性的。数据都是缓存在内存中
。master-slave
(主从复制)同步。2. 多样的数据结构存储持久化数据
1. 安装过程详解
如果虚拟机上有相应的gcc环境的话,请跳过该环节。查看命令:gcc -- version
。否则就执行以下命令:
yum install centos-release-scl scl-utils-build yum install -y devtoolset-8-toolchain scl enable devtoolset-8 bash
tar -zxvf redis-6.2.1.tar.gz
cd redis-6.2.1
Jemalloc/jemalloc.h
:没有那个文件。我们可以通过以下方法解决。make distclean
make install
2. 安装目录:/usr/local/bin
3. 启动方式
# 前台启动 # 前台启动的话,当关闭窗口的时候会导致其关闭 redis-server # 后台启动 # 为避免我们将redis.conf文件改错的话,我们需要将其备份一份到/etc目录下 cp redis.conf /etc # 然后对/etc目录下的redis.conf文件进行修改 # 将daemonize no 改成yes # 而后台启动的话,窗口关闭的话不会导致其关闭 # 操作步骤如下 vi /etc/redis.conf # 通过/daem找到相应的行将no改为yes # 启动 redis-server /etc/redis.conf # 用客户端访问 redis-cli # 可以通过ping命令进行测试,如果显示PONG证明启动成功 # 关闭方式 shutdown exit # 或者我们可以通过 进程进行杀死相关进程 ps -ef | grep redis kill -9 相关进程号
4. 相关知识介绍
6379
16
个数据库,初始默认使用0
号库。5. 单线程 + 多路IO复用
此处的黄牛党买票就属于单线程,而多个顾客属于多个IO。当黄牛党买到票之后,那么她会通知相应的顾客来拿相应的票。但是如果没有买到相应的票的话,顾客也不会一直等待。他会去做其他事情。从而使得CPU没有空闲,提高了CPU的效率。
# 查看当前库的所有key key * # 判断某个key 是否存在 exists key # 查看你的key是什么类型 type key # 删除指定的key数据 del key # 根据value选择非阻塞删除 unlink key # 仅将keys从keyspace元数据中删除,真正的删除会在后续异步操作。 # 为给定的key设置过期时间 expire key 10 # 查看还有多少秒过期, -1 表示永不过期,-2表示已过期 ttl key # 切换数据库 select index # 相应的数据库编号 # 查看当前数据库的key数量 dbsize # 清空当前库 flushdb
1. 简介
String
时Redis最基本的数据类型,它与Memcached一样是一个key对应一个value。String
类型是二进制安全的,意味着Redis的string可以包含任何数据。且一个Redis中字符串value最多可以是512M。2. 常用命令
# 添加键值对 set key value # 查询对应键值 get key # 将给定的value追加到原值的末尾 append key value # 获得值的长度 strlen key # 只有在key不存在的时候,设置key的值 setnx key value # 当key中存储的值为数字类型的时候,将数字值增1 incr key # 当key中存储的值为数字类型的时候,将数字值键1 decr key # 将key中存储的值增减一定的步长 incrby/decrby key <步长>
3. 原子性
原子性
操作是指不会被线程调度机制打断的操作。4. 案例分析
java中的i ++ 不是原子操作,它主要分为
取值, ++ ,赋值
三个阶段。
最后的值为2 ~ 200。就拿上方图片来做说明,a线程执行了99次,然后此时i的值为99.但是此时b线程打断a线程获得了执行权。由于b线程已经执行过了取值操作,然后就是++ 和 赋值操作。得到1之后一直执行到i = 100。然后就是a线程执行++步骤再进行赋值得到此时i = 2。而200则是a线程执行了100次,b线程再按序执行100次。
4. 命令
# 同时设置一个或多个key-value对 mset key1 value1 key2 value2 ... # 同时获取一个或多个value mget key1 key2 key3 ... # 同时设置一个或多个key-value对,当且仅当所有给定key都不存在。如果其中有一个存在,那么就会添加时报。由于其是原子性的,有一个失败则全都失败。 msetnx key1 value1 key2 value2... # 获得值得范围,类似于java中得substring,它这包含了起始位置和终止位置。 getrange key 起始位置 结束位置 # 使用value覆盖key所存储的字符串值,从起始位置开始,(索引是从0开始的) setrange key <起始位置> value # 设置键值的同时设置过期时间,单位为秒 setex key <过期时间> value # 获取旧值的同时设置新值 getset key value
5. 底层实现的数据结构
1. 简介
2. 常用命令
# 从左边/右边插入一个或多个值 lpush/rpush key value1 value2 value3 .... # 从左边/右边吐出一个值。值在键在,值光键亡。 lpop/rpop key # 从key1列表右边吐出一个值,插到key2列表左边。 rpoplpush key1 key2 # 按照索引下标获得元素(从左到右) lrange key start stop # 0左边第一个,-1右边第一个,(0 ~ -1表示获取所有) lrange mylist 0 -1 # 按照索引下标获得元素(从左到右) lindex key index # 获得列表长度 llen key # 在value的前面/后面插入newvalue插入值 linsert key before/after value newvalue # 从左边删除n个value(从左到右) lrem key n value # 将列表key下标为index的值替换成value lset key index value
3. 数据结构
quickList
。双向指针
串起来使用。这样既满足了快速的插入删除性能,又不会出现太大的空间冗余。1. 简介
2. 常用命令
# 将一个或多个 member 元素加入到集合 key 中,已经存在的 member 元素将被忽略,也就是可以去重 sadd key value1 value2 ..... # 取出该集合的所有值。 smembers key # 判断集合key是否为含有该value值,有1,没有0 sismember key value # 返回该集合的元素个数。 scard key # 删除集合中的某一个或者多个元素。 srem key value1 value2 .... # 随机从该集合中吐出一个值。 spop key # 随机从该集合中取出n个值。不会从集合中删除 。 srandmember key n # 把集合中一个值从一个集合移动到另一个集合 smove source destination value # 返回两个集合的交集元素。 sinter key1 key2 # 返回两个集合的并集元素。 sunion key1 key2 # 返回两个集合的差集元素(key1中的,不包含key2中的) sdiff key1 key2
3. 数据结构
dict
字典,字典是用哈希表
实现的。1. 简介
Redis hash
是一个键值对集合。Redis hash
是一个string类型的field和value的映射表,hash特别适合用于存储对象。类似Java里面的Map<String,Object>key(用户ID) + field(属性标签)
就可以操作对应属性数据了,既不需要重复存储数据,也不会带来序列化和并发修改控制的问题2. 常用命令
# 给key集合中的 field键赋值value hset key field value # 从key1集合field取出 value hget key1 field # 批量设置hash的值 hmset key1 field1 value1 field2 value2... # 查看哈希表 key 中,给定域 field 是否存在。 hexists key1 field # 列出该hash集合的所有field hkeys key # 列出该hash集合的所有value hvals key # 为哈希表 key 中的域 field 的值加上增量 1 -1 hincrby key field increment # 将哈希表 key 中的域 field 的值设置为 value ,当且仅当域 field 不存在 . hsetnx key field value
3. 数据结构
ziplist
(压缩列表),hashtable
(哈希表)。field-value
长度较短且个数较少时,使用ziplist
,否则使用hashtable
。1. 简介
zset
与普通集合set非常相似,是一个没有重复元素的字符串集合
。评分(score)或者次序(position)
来获取一个范围的元素。2. 常用命令
# 将一个或多个 member 元素及其 score 值加入到有序集 key 当中。 zadd key score1 value1 score2 value2… # 返回有序集 key 中,下标在start stop之间的元素,带WITHSCORES,可以让分数一起和值返回到结果集。 zrange key start stop [WITHSCORES] # 返回有序集 key 中,所有 score 值介于 min 和 max 之间(包括等于 min 或 max )的成员。有序集成员按 score 值递增(从小到大)次序排列。 zrangebyscore key min max [withscores] [limit offset count] # 同上,改为从大到小排列。 zrevrangebyscore key max min [withscores] [limit offset count] # 为元素的score加上增量 zincrby key increment value # 删除该集合下,指定值的元素 zrem key value # 统计该集合,分数区间内的元素个数 zcount key min max # 返回该值在集合中的排名,从0开始。 zrank key value
3. 数据结构