本文主要包括 NoSQL入门、Redis环境搭建和Redis入门三个部分。
一 、NoSQL入门
NoSQL(not only sql),泛指非关系型数据库,这类型的数据存储不需要固定的的模式,无需多余操作就可以横向扩展.
1 为什么要用NoSQL
NoSQL出现之前,MySQL的发展过程:
- 单机MySQL
- Memcached(缓存)+MySQL+垂直拆分
- MySQL主从读写分离
- 分表分库+水平拆分+MySQL集群
- MySQL的扩展性瓶颈
也因此NoSQL出现
2 NoSQL优势
- 易扩展
- 大数据量高性能
- 多样灵活的数据模型
3 RDBMS和NoSQL比较
- RDBMS
--高度组织化结构化数据
--数据和关系都存储在单独的表中
--数据操纵语言,数据定义语言
--严格的一致性
--基础事务 - NoSQL
--代表着不仅仅是SQL
--没有声明性查询语言
--没有预定义的模式
--键值对存储,列存储,文档存储,图形数据库
--最终一致性,而非ACID属性
--CAP定律
--高性能,高可用和可伸缩性
4 3V+3高
- 大数据时代的3V
--海量volume
--多样variety
--实时velocity - 互联网需求的3高
--高并发
--高可扩
--高性能
5 当下的NoSQL经典应用
当下的应用是sql和nosql一起使用
6 NoSQL的四大分类
- KV键值对 ,典型介绍
--新浪:BerkeleyDB+redis
--美团:redis+tair
--阿里/百度:memcache+redis - 文档型数据库(bson格式比较多)
--CouchDB
--MongDB:基于分布式文件存储的数据库,介于关系数据库和非关系数据库之间的产品,是非关系数据库中功能最丰富,最像关系数据库的 - 列存储数据库
--Cassandra,HBase
--分布式文件系统 - 图关系数据库
--专注于构建图谱关系,如Neo4J,InfoGrid - 四者对比
分类 | Examples举例 | 典型应用场景 | 数据模型 | 优点 | 缺点 |
---|---|---|---|---|---|
键值(key-value) | Key 指向 Value 的键值对,通常用hash table来实现 | ||||
列存储数据库 | Cassandra, HBase, Riak | 分布式的文件系统 | 以列簇式储,将同一列数据存在一起 | 查找速度快,可扩展性强,更容易进行分布式扩展 | 功能相对局限 |
文档型数据库 | CouchDB, MongoDb | Web应用(与Key-Value类似,Value是结构化的,不同的是数据库能够了解Value的内容) | Key-Value对应的键值对,Value为结构化数据 | 数据结构要求不严格,表结构可变,不需要像关系型数据库一样需要预先定义表结构 | 查询性能不高,而且缺乏统一的查询语法。 |
图形(Graph)数据库 | Neo4J, InfoGrid, Infinite Graph | 社交网络,推荐系统等。专注于构建关系图谱 | 图结构 | 利用图结构相关算法。比如最短路径寻址,N度关系查找等 | 很多时候需要对整个图做计算才能得出需要的信息,而且这种结构不太好做分布式的集群方案。 |
7 分布式数据库CAP原理
7.1 关系型数据库遵循ACID规则
事务在英文中是transaction,和现实世界中的交易很类似,它有如下四个特性:
A (Atomicity) 原子性
原子性很容易理解,也就是说事务里的所有操作要么全部做完,要么都不做,事务成功的条件是事务里的所有操作都成功,只要有一个操作失败,整个事务就失败,需要回滚。比如银行转账,从A账户转100元至B账户,分为两个步骤:1)从A账户取100元;2)存入100元至B账户。这两步要么一起完成,要么一起不完成,如果只完成第一步,第二步失败,钱会莫名其妙少了100元。
C (Consistency) 一致性
一致性也比较容易理解,也就是说数据库要一直处于一致的状态,事务的运行不会改变数据库原本的一致性约束。
I (Isolation) 独立性
所谓的独立性是指并发的事务之间不会互相影响,如果一个事务要访问的数据正在被另外一个事务修改,只要另外一个事务未提交,它所访问的数据就不受未提交事务的影响。比如现有有个交易是从A账户转100元至B账户,在这个交易还未完成的情况下,如果此时B查询自己的账户,是看不到新增加的100元的
D (Durability) 持久性
持久性是指一旦事务提交后,它所做的修改将会永久的保存在数据库上,即使出现宕机也不会丢失。
7.2 CAP原理
C:Consistency(强一致性)
A:Availability(可用性)
P:Partition tolerance(分区容错性)
CAP理论的核心是:一个分布式系统不可能同时很好的满足一致性,可用性和分区容错性这三个需求,而由于当前的网络硬件肯定会出现延迟丢包等问题,所以分区容忍性是我们必须需要实现的。所以我们只能在一致性和可用性之间进行权衡最多只能同时较好的满足两个。
因此,根据 CAP 原理将 NoSQL 数据库分成了满足 CA 原则、满足 CP 原则和满足 AP 原则三 大类:
CA - 单点集群,满足一致性,可用性的系统,通常在可扩展性上不太强大
CP - 满足一致性,分区容忍必的系统,通常性能不是特别高。
AP - 满足可用性,分区容忍性的系统,通常可能对一致性要求低一些。
大多数web应用,其实并不需要强一致性。因此牺牲C换取P,这是目前分布式数据库产品的方向。Redis满足CP
- 一致性与可用性的决择
对于web2.0网站来说,关系数据库的很多主要特性却往往无用武之地
①数据库事务一致性需求
很多web实时系统并不要求严格的数据库事务,对读一致性的要求很低, 有些场合对写一致性要求并不高。允许实现最终一致性。
②数据库的写实时性和读实时性需求
对关系数据库来说,插入一条数据之后立刻查询,是肯定可以读出来这条数据的,但是对于很多web应用来说,并不要求这么高的实时性,比方说发一条消息之 后,过几秒乃至十几秒之后,我的订阅者才看到这条动态是完全可以接受的。
③对复杂的SQL查询,特别是多表关联查询的需求
任何大数据量的web系统,都非常忌讳多个大表的关联查询,以及复杂的数据分析类型的报表查询,特别是SNS类型的网站,从需求以及产品设计角 度,就避免了这种情况的产生。往往更多的只是单表的主键查询,以及单表的简单条件分页查询,SQL的功能被极大的弱化了。
7.3 BASE
为了解决关系数据库强一致性引起的问题而引起的可用性降低而提出的解决方案。
BASE其实是下面三个术语的缩写:
基本可用(Basically Available)
软状态(Soft state)
最终一致(Eventually consistent)
它的思想是通过让系统放松对某一时刻数据一致性的要求来换取系统整体伸缩性和性能上改观。为什么这么说呢,缘由就在于大型系统往往由于地域分布和极高性能的要求,不可能采用分布式事务来完成这些指标,要想获得这些指标,我们必须采用另外一种方式来完成,这里BASE就是解决这个问题的办法
7.4 分布式集群
详细可参考https://blog.csdn.net/q975583865/article/details/81712350
二、Redis环境搭建
系统Ubuntu 18.04.2,下面将详细介绍使用源码编译安装Redis的过程
1 安装构建工具:
sudo apt-get update
sudo apt-get install make gcc python-dev
2 下载源码
从https://redis.io/download下载最新的stable版本Redis源码,解压后进入redis目录
wget http://download.redis.io/redis-stable.tar.gz
tar xzvf redis-stable.tar.gz
cd redis-stable
3 编译安装
make
make test
sudo make install
4 配置
Redis配置目录通常位于/etc/目录中,我们需要自行创建并将Redis中自带的redis.conf配置文件复制过去并修改。
sudo mkdir /etc/redis
sudo cp /home/tiana/redis-5.0.5/redis.conf /etc/redis
sudo vim /etc/redis/redis.conf
5 创建Redis系统单元文件
sudo vim /etc/systemd/system/redis.service
加入
[Unit]
Description=Redis In-Memory Data Store
After=network.target
[Service]
User=redis
Group=redis
ExecStart=/usr/local/bin/redis-server /etc/redis/redis.conf
ExecStop=/usr/local/bin/redis-cli shutdown
Restart=always
[Install]
WantedBy=multi-user.target
6 创建Redis用户,组和目录
sudo adduser --system --group --no-create-home redis
sudo mkdir /var/lib/redis
sudo chown redis:redis /var/lib/redis
sudo chmod 770 /var/lib/redis
7 启动和测试Redis
sudo systemctl start redis
sudo systemctl status redis
启动后如图
打开另一终端测试,测试命令和结果如下图
最后输入exit退出,重启服务
sudo systemctl restart redis
再次按照上述测试命令测试,最后输入
sudo systemctl enable redis
会输出Created symlink from /etc/systemd/system/multi-user.target.wants/redis.service to /etc/systemd/system/redis.service.
8 出现的问题:
1.输入make test 后出现“You need tcl 8.5 or newer in order to run the Redis test”。
解决参考https://blog.csdn.net/zhangshu123321/article/details/51440106
wget http://downloads.sourceforge.net/tcl/tcl8.6.1-src.tar.gz
tar xzvf tcl8.6.1-src.tar.gz
cd tcl8.6.1/unix
sudo ./configure
sudo make
sudo make install
9 其他知识
- Redis是单进程模型来处理客户端的请求。对读写等事件的响应是通过对epoll函数的包装来做到的。Redis的实际处理速度完全依靠主进程的执行效率。epoll是Linux内核为处理大批量文件描述符而作了改进的epoll,是Linux下多路复用IO接口select/poll的增强版本,它能显著提高程序在大量并发连接中只有少量活跃的情况下的系统CPU利用率。
这也是Redis快的原因之一,更多可参考https://blog.csdn.net/chenyao1994/article/details/79491337
- 默认16个数据库,类似数组下表从零开始,初始默认使用零号库。Redis索引都是从零开始。可以使用
SELECT <dbid>
命令在连接上指定数据库id。 - Redis是统一密码管理,16个库都是同样密码,要么都OK要么一个也连接不上。
三、Redis入门
官网:
http://www.redis.cn/
https://redis.io/
- Redis:REmote DIctionary Server(远程字典服务器)
- 是完全开源免费的,Redis是一个开源的使用ANSI C语言编写、遵守BSD协议、支持网络、可基于内存亦可持久化的日志型、Key-Value数据库,并提供多种语言的API。
- Redis可以存储键与5种不同数据结构类型之间的映射,这5种数据结构类型为String、List、Set、Hash和Zset。因此它通常被称为数据结构服务器。
- Redis 与其他 key - value 缓存产品有以下三个特点
①Redis支持数据的持久化,可以将内存中的数据保持在磁盘中,重启的时候可以再次加载进行使用
②Redis不仅仅支持简单的key-value类型的数据,同时还提供list,set,zset,hash等数据结构的存储
③Redis支持数据的备份,即master-slave模式的数据备份
五大数据类型
* String
- String 类型是 Redis 最基本的数据类型,string 类型的值最大能存储 512MB。
- String类型是二进制安全的。意思是 redis 的 string 可以包含任何数据。比如jpg图片或者序列化的对象。
-
常见命令示例:
a.set 键名 值,命令执行成功时会返回ok
b.get 键名,获取存储在键中的值,若不存在则返回nil
c.del 键名,删除键值对
* List
- 一个列表结构可以有序地存储多个字符串。
-
命令示例
a.lpush和rpush分别用于将元素推入列表的左端(left end)和右端(right end)。
在向列表推入新元素之后,该命令会返回列表当前的长度
b.lpop和rpop分别用于从列表的左端和右端弹出元素。
c.lindex命令用于获取列表在给定位置上的一个元素。
d.lrange用于获取列表在给定范围上的所有元素
使用0为范围的起始索引,-1为范围的结束索引,可以取出列表包含的所有元素
e.lpop从列表的左端弹出一个值,并返回被弹出的值
* Set
- Redis 的 Set 是 String 类型的无序集合。集合成员是唯一的,这就意味着集合中不能出现重复的数据。
- Redis 中集合是通过哈希表实现的,所以添加,删除,查找的复杂度都是 O(1)。
- 命令示例
a.sadd 在尝试将一个元素添加到集合的时候,命令返回1表示这个元素将被成功地添加到集合里,返回0表示这个元素已经存在.
b.smembers获取集合包含的元素将得到一个由元素组成的序列.如果元素非常多,执行命令会很慢,慎用.
c .sismember可检查一个元素是否存在于集合中.
d .srem 移除集合中的元素,会返回被移除元素的数量.
* Hash
- 是一个string类型的field和value的映射表,value可以是字符串和数字值,hash特别适合用于存储对象。
-
命令示例
a.hset 添加键值对,命令会返回一个值表示键是否已经存在于散列表中.
b.hgetall获取所有键值对,hget获取某个键的值.
c.hdel删除,返回值表示在删除之前该值是否存在于散列表中.
* Zset
- 用于存储键值对,且不允许重复.
- 有序集合的键被称为成员,每个成员都是各不相同的
- 有序集合的值被称为分值,分值必须为浮点数.Redis通过分值为集合进行从小到大的排序.
- 根据成员访问元素(同散列),又可以根据分值以及分值的排列顺序来访问元素的结构.
- 有序集合的成员是唯一的,但分值可以重复.
- 命令示例:
a.zadd添加元素,返回新添加元素的数量
b.zrange获取所有元素
c.zangebyscore 根据分值获取元素
d.zrem移除元素,返回值表示被移除元素的数量
本文参考 https://www.howtoing.com/how-to-install-redis-from-source-on-ubuntu-18-04
<<Redis实战>>