NoSQL概述
数据库类型
RDBMS
关系型数据库管理系统
- Relational Database Management System
- 按照预先设置的组织结构,将数据存储在物理介质上
- 数据之间可以做关联操作
- 银行就是典型的关系型数据库
主流的RDBMS软件
- MySQL
- MariaDB
- Oracle
- DB2
- SQL Server
NoSQL
非关系型数据库
- NoSQL(NoSQL=Not Only SQL)意为“不仅仅是SQL”
- 泛指非关系型数据库
- 不需要预先定义数据存储结构
- 每条记录可以有不同的数据类型和字段数据
- 微信聊天等适合使用非关系型数据库
主流的NoSQL软件
- Memcached
- Redis
- MongoDB
- COuchDB
- Neo4j
- FlockDB
非关系型数据库和关系型数据库优缺点
数据库类型 | 特点 | 优点 | 缺点 |
关系型数据库 | 1.关系型数据库,是指采用了关系模型来组织数据的数据库 2.关系型数据库的最大特点就是事物的一致性 3.简单来说,关系模型值的就是二维表格模型,而一个关系型数据库就是由二维表及其之间的联系所组成的一个数据组织 | 1.容易理解,二维表结构是非常贴近逻辑世界的一个概念,关系模型相对网状、层次等其他模型来说更容易理解 2.使用方便,通用的SQL语言使得操作关系型数据库非常方便 3.易于维护,丰富的完整性(实体完整性、参照完整性和用户定义的完整性)大大减低了数据冗余和数据不一致的概率 4.支持SQL,可用于复杂的查询 | 1.为了维护一致性所付出的巨大代价就是其读写性能较差 |
2.固定的表结构 | |||
3.高并发读写需求 | |||
4.海量数据的高效率读写 | |||
非关系型数据库 | 1.使用键值对存储数据 2.分布式 3.一般不支持ACID特性 4.是一种数据结构化存储方法的集合 | 1.无需经过SQL层的解析,读写性能高 2.基于键值对,数据没有耦合性,容易扩展 3.存储数据的格式:nosql的存储格式是key,value形式、图片形式等,而关系型数据库只支持基础类型 | 1.不提供SQL支持,学习和使用成本较高 2.无事务处理,附加功能bi和报表等支持也不好 |
部署redis服务
redis介绍
redis
- Remote Dictionary Server(远程字典服务器)
- 是一款高性能的(key/values)分布式内存数据库
- 支持数据持久化(定期把内存里的数据存储到硬盘)
- 支持多种数据类型string、list、hash...
- 支持master-slave模式数据备份
- 可再生的数据以及被频繁使用的数据被存入内存中,加快网站的访问速度,访问时从内存存储数据库内查找
- 中文网站 http://www.redis.cn/
- 网盘链接链接 https://pan.baidu.com/s/11QYBLKiBOoF2QoI49GNOQQ
提取码:zwxf
搭建redis服务器
1.在51上安装redis软件
[root@host51 ~]# systemctl stop mysqld
[root@host51 ~]# rpm -q gcc #查看编译安装工具是否安装
未安装软件包 gcc
[root@host51 ~]# yum -y install gcc
[root@host51 ~]# cd /opt
[root@host51 opt]# tar -zxvf redis-4.0.8.tar.gz
[root@host51 opt]# cd redis-4.0.8/
[root@host51 redis-4.0.8]# ls
00-RELEASENOTES COPYING Makefile redis.conf runtest-sentinel tests
BUGS deps MANIFESTO runtest sentinel.conf utils
CONTRIBUTING INSTALL README.md runtest-cluster src
[root@host51 redis-4.0.8]# make install
[root@host51 redis-4.0.8]# redis- #redis相关命令
redis-benchmark redis-check-rdb redis-sentinel
redis-check-aof redis-cli redis-server
------------------------------------------------------------------
2.初始化配置
[root@host51 redis-4.0.8]# ./utils/install_server.sh #一路回车
...
Port : 6379 #端口
Config file : /etc/redis/6379.conf #主配置文件
Log file : /var/log/redis_6379.log #日志文件
Data dir : /var/lib/redis/6379 #数据库目录
Executable : /usr/local/bin/redis-server #服务启动程序
Cli Executable : /usr/local/bin/redis-cli #命令行连接命令
Starting Redis server... #初始化会默认将服务启动
[root@host51 redis-4.0.8]# ls /etc/redis/6379.conf
/etc/redis/6379.conf
[root@host51 redis-4.0.8]# ls /var/log/redis_6379.log
/var/log/redis_6379.log
[root@host51 redis-4.0.8]# ls /var/lib/redis/6379/
[root@host51 redis-4.0.8]# ls /usr/local/bin/
redis-benchmark redis-check-rdb redis-sentinel
redis-check-aof redis-cli redis-server
[root@host51 redis-4.0.8]# ss -nutlp | grep 6379 #查看端口
tcp LISTEN 0 128 127.0.0.1:6379 *:* users:(("redis-server",pid=5489,fd=6))
[root@host51 redis-4.0.8]# ps -C redis-server #查看进程
PID TTY TIME CMD
5489 ? 00:00:00 redis-server
[root@host51 redis-4.0.8]# /etc/init.d/redis_6379 stop #关闭redis服务
Stopping ...
Redis stopped
[root@host51 redis-4.0.8]# ss -nutlp | grep 6379
[root@host51 redis-4.0.8]# /etc/init.d/redis_6379 start #启动redis服务
Starting Redis server...
[root@host51 redis-4.0.8]# ss -nutlp | grep 6379
tcp LISTEN 0 128 127.0.0.1:6379 *:* users:(("redis-server",pid=5581,fd=6))
--------------------------------------------------------------------
3.连接redis服务
连接服务操作:
[root@host51 redis-4.0.8]# redis-cli
127.0.0.1:6379> ping #测试是否连接成功,默认连接127.0.0.1的6379端口
PONG #出现pong即代表连接成功 可以正常管理数据
常用命令
- set key名 key值 #存储一个key值
- mset key名列表 #存储多个key值
- get key名 #获取key值
- mget #获取多个key值
- select 数据库编号0-15 #切换库,有0-15共16个库,默认是0号库
- keys * #显示所有key名
- keys a? #显示指定key名
- exists key名 #测试key名是否存在
- ttl key名 #查看key生存时间
- type key名 #查看key类型
- move key名 #移动key到指定库
- expire key名 数字 #设置key有效时间
- del key名 #删除指定的key
- flushall #删除内存里所有的key
- flushdb #删除所在库的所有key
- save #保存所有的key到硬盘
- shutdown #停止服务
常用命令:
127.0.0.1:6379> set class 111111 #存数据
OK
127.0.0.1:6379> keys * #查看内存中所有变量
1) "class"
127.0.0.1:6379> get class #取数据
"111111"
127.0.0.1:6379> set age 55
OK
127.0.0.1:6379> keys *
1) "class"
2) "age"
127.0.0.1:6379> get age
"55"
127.0.0.1:6379> exit #断开连接
127.0.0.1:6379> mset name tian sex girl age 111 存储多个数据
OK
127.0.0.1:6379> keys *
1) "class"
2) "age"
3) "name"
4) "sex"
127.0.0.1:6379> get age
"111"
127.0.0.1:6379> mget name sex #获取多个数据
1) "tian"
2) "girl"
127.0.0.1:6379> select 15 #切换库,有0-15共16个库,默认是0号库
OK
127.0.0.1:6379[15]> select 0
OK
127.0.0.1:6379> select 15
OK
127.0.0.1:6379[15]> keys *
(empty list or set)
127.0.0.1:6379[15]> select 0
OK
127.0.0.1:6379> keys name
1) "name"
127.0.0.1:6379> keys a? #显示指定的key名
(empty list or set)
127.0.0.1:6379> keys a??
1) "age"
127.0.0.1:6379> keys a* #显示所有以a开头的变量名
1) "age"
127.0.0.1:6379> keys ??? #显示所有变量名是三位的
1) "age"
2) "sex"
127.0.0.1:6379> get age
"111"
127.0.0.1:6379> set age 120
OK
127.0.0.1:6379> get age
"120"
127.0.0.1:6379> exists name #查看变量名是否存在,1为存在,0为不存在
(integer) 1
127.0.0.1:6379> exists age
(integer) 1
127.0.0.1:6379> exists user x
(integer) 0
127.0.0.1:6379> exists user name #查看多个变量名时,只要有一个存在就显示1
(integer) 1
127.0.0.1:6379> ttl age #查看变量的生存时间,-1为永久存在,需要手动删除,-2为生存时间已经过期,默认为-1,存在内存中
(integer) -1
127.0.0.1:6379> get age
"120"
127.0.0.1:6379> type name #查看变量的类型,string为字符类型
string
127.0.0.1:6379> lpush hostname x y z
(integer) 3
127.0.0.1:6379> type hostname
list
127.0.0.1:6379> select 2
OK
127.0.0.1:6379[2]> select 0
OK
127.0.0.1:6379> move age 2 #将age变量移动到2号库
(integer) 1
127.0.0.1:6379> keys * #此时0号库已经没有了age类型
1) "class"
2) "hostname"
3) "name"
4) "sex"
127.0.0.1:6379> select 2
OK
127.0.0.1:6379[2]> keys *
1) "age"
127.0.0.1:6379[2]> select 0
OK
127.0.0.1:6379> select 2
OK
127.0.0.1:6379[2]> ttl age
(integer) -1
127.0.0.1:6379[2]> expire age 15 #将age类型的有效时间设为15秒
(integer) 1
127.0.0.1:6379[2]> ttl age #再次查看,此时剩9秒
(integer) 9
127.0.0.1:6379[2]> ttl age #此时该变量已经过了有效时间
(integer) -2
127.0.0.1:6379[2]> keys *
(empty list or set)
127.0.0.1:6379[2]> select 0
OK
127.0.0.1:6379> del name #删除name变量
(integer) 1
127.0.0.1:6379> flushdb #删除所在库里所有的变量名
OK
127.0.0.1:6379> keys *
(empty list or set)
127.0.0.1:6379> flushall #删除内存里所有变量名
OK
127.0.0.1:6379> set x 19
OK
127.0.0.1:6379> keys *
1) "x"
127.0.0.1:6379> get x
"19"
127.0.0.1:6379> save #手动保存变量到硬盘,在/var/lib/redis/6379/目录中
OK
[root@host51 ~]# ls /var/lib/redis/6379/
dump.rdb
127.0.0.1:6379> shutdown #停止服务
not connected> ping #此时再次ping显示服务拒绝
Could not connect to Redis at 127.0.0.1:6379: Connection refused
not connected> exit
[root@host51 redis-4.0.8]# ss -nutlp | grep 6379 #再次查看端口
[root@host51 redis-4.0.8]# /etc/init.d/redis_6379 start
Starting Redis server...
[root@host51 redis-4.0.8]# redis-cli
127.0.0.1:6379> ping
PONG
修改redis服务的运行参数
名称 | 说明 |
NETWORK | 网络 |
GENERAL | 常规 |
SNAPSHOTTNG | 快照 |
REPLICATION | 复制 |
SECURITY | 安全 |
CLIENTS | 客户端 |
MWMORY MANAGEMENT | 内存管理 |
数据单位
常用配置
- port 6379 #端口
- bind 127.0.0.1 #IP地址
- daemonize yes #守护进程方式运行
- databases 16 #数据库个数
- logfile /var/log/redis_6379.log #日志文件
- maxclients 10000 #并发连接数量
- dir /var/lib/redis/6379 #数据库目录
内存管理
- volatile-lru #最近最少使用(针对设置了TTL的key)
- allkeys-lru #删除最少使用的key(针对所有的key)
- allkeys-lfu #从所有的key中清除使用频率最少的key
- volatile-lfu #从所有配置了过期时间的key中清除使用频率最少的key
- volatile-random #在设置了TTL的key里随机移除
- allkeys-random #随机移除key
- volatile-ttl (minor TTL) #移除最近过期的key
-noeviction #不删除
-----------------------------------------------------------------------------------------------------
优化设置
- maxmemory #最大内存
- maxmemory-policy #定义使用策略
- maxmemory-samples #选取key模板的个数(针对lru和ttl策略)
修改服务IP地址端口号设置连接密码
[root@host51 ~]# /etc/init.d/redis_6379 stop #修改配置文件前停止服务!!
Stopping ...
Redis stopped
[root@host51 ~]# vim /etc/redis/6379.conf
70 bind 192.168.4.51 #允许192.168.4.51主机登录本机redis
93 port 6351 #修改redis端口号为6351
501 requirepass 123456 #192.168.4.51主机登录时连接的密码为123456
[root@host51 ~]# sed -n '70p;93p;501p' /etc/redis/6379.conf
bind 192.168.4.51
port 6351
requirepass 123456
[root@host51 ~]# /etc/init.d/redis_6379 start #重启服务
Starting Redis server...
[root@host51 ~]# ss -nutlp | grep 6351 #现在的端口号变为6351
tcp LISTEN 0 128 192.168.4.51:6351 *:* users:(("redis-server",pid=5707,fd=6))
连接:
[root@host51 ~]# redis-cli #此时再使用原来的命令进入redis是进不去的
Could not connect to Redis at 127.0.0.1:6379: Connection refused
[root@host51 ~]# redis-cli -h 192.168.4.51 -p 6351
192.168.4.51:6351> ping #进入成功后要输入密码才可以进行操作
(error) NOAUTH Authentication required.
192.168.4.51:6351> auth 123456
OK
192.168.4.51:6351> ping
PONG
[root@host51 ~]# redis-cli -h 192.168.4.51 -p 6351 -a 123456
192.168.4.51:6351> ping
PONG
部署LNMP+redis
部署LNMP
安装软件
Nginx源码包软件链接:https://pan.baidu.com/s/1GaOyufUBOln4bv4Ln3bEAA
提取码:tgnj
redis源码包链接:https://pan.baidu.com/s/1sHmIQXhjKCpwwQMnWti0Yg
提取码:z25q
1.在50主机部署LNMP
要求必须要有Nginx源码包以及redis包
[root@host50 opt]# rpm -q gcc
未安装软件包 gcc
[root@host50 opt]# rpm -q pcre-devel
未安装软件包 pcre-devel
[root@host50 opt]# rpm -q zlib-devel
未安装软件包 zlib-devel
[root@host50 opt]# yum -y install gcc pcre-devel zlib-devel #安装依赖
[root@host50 opt]# tar -zxvf /opt/nginx-1.12.2.tar.gz #解压
[root@host50 opt]# cd nginx-1.12.2/
[root@host50 nginx-1.12.2]# ./configure
[root@host50 nginx-1.12.2]# make && make install #编译安装
[root@host50 nginx-1.12.2]# yum -y install php-fpm
修改配置
[root@host50 nginx-1.12.2]# vim +65 /usr/local/nginx/conf/nginx.conf
65 location ~ \.php$ {
66 root html;
67 fastcgi_pass 127.0.0.1:9000;
68 fastcgi_index index.php;
69 # fastcgi_param SCRIPT_FILENAME /scripts$fastcgi_script_name;
70 include fastcgi.conf;
71 }
[root@host50 nginx-1.12.2]# ls /usr/local/nginx/conf/
fastcgi.conf (获取Nginx内置变量的值) koi-utf nginx.conf uwsgi_params
fastcgi.conf.default koi-win nginx.conf.default uwsgi_params.default
fastcgi_params mime.types scgi_params win-utf
fastcgi_params.default mime.types.default scgi_params.default
[root@host50 nginx-1.12.2]# systemctl start php-fpm #开启php服务
[root@host50 nginx-1.12.2]# ss -nutlp | grep 9000
tcp LISTEN 0 128 127.0.0.1:9000 *:* users:(("php-fpm",pid=4277,fd=0),("php-fpm",pid=4276,fd=0),("php-fpm",pid=4275,fd=0),("php-fpm",pid=4274,fd=0),("php-fpm",pid=4273,fd=0),("php-fpm",pid=4272,fd=6))
[root@host50 nginx-1.12.2]# /usr/local/nginx/sbin/nginx -t #查看配置文件是否书写错误
nginx: the configuration file /usr/local/nginx/conf/nginx.conf syntax is ok
nginx: configuration file /usr/local/nginx/conf/nginx.conf test is successful
启动服务
[root@host50 nginx-1.12.2]# systemctl start php-fpm #开启php服务
[root@host50 nginx-1.12.2]# ss -nutlp | grep 9000
tcp LISTEN 0 128 127.0.0.1:9000 *:* users:(("php-fpm",pid=4277,fd=0),("php-fpm",pid=4276,fd=0),("php-fpm",pid=4275,fd=0),("php-fpm",pid=4274,fd=0),("php-fpm",pid=4273,fd=0),("php-fpm",pid=4272,fd=6))
[root@host50 nginx-1.12.2]# /usr/local/nginx/sbin/nginx #起服务
[root@host50 nginx-1.12.2]# ss -nutlp | grep 80
tcp LISTEN 0 128 *:80 *:* users:(("nginx",pid=4290,fd=6),("nginx",pid=4289,fd=6))
测试配置
root@host50 nginx-1.12.2]# vim /usr/local/nginx/html/test.php #书写一个测试脚本
<?php
$i=99 ;
echo $i ;
?>
测试LNMP环境是否搭建成功:
[root@host50 nginx-1.12.2]# netstat -nutlp | grep 80
tcp 0 0 0.0.0.0:80 0.0.0.0:* LISTEN 4289/nginx: master
[root@host50 nginx-1.12.2]# netstat -nutlp | grep 9000
tcp 0 0 127.0.0.1:9000 0.0.0.0:* LISTEN 4272/php-fpm: maste
[root@host50 nginx-1.12.2]# curl 192.168.4.50/test.php
99
用真机访问测试页面http://192.168.4.50/test.php
配置支持redis
运行redis服务
安装功能模块,PHP扩展
[root@host50 nginx-1.12.2]# which php
/usr/bin/which: no php in (/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/root/bin)
[root@host50 nginx-1.12.2]# yum -y install php #安装依赖
[root@host50 nginx-1.12.2]# which php
/usr/bin/php
[root@host50 nginx-1.12.2]# php -m | grep -i redis #此时没有安装支持连接redis的模块
[root@host50 nginx-1.12.2]# cd /opt #查看是否有php-redis软件包
[root@host50 opt]# ls
nginx-1.12.2 nginx-1.12.2.tar.gz php-redis-2.2.4.tar.gz redis-4.0.8.tar.gz
[root@host50 opt]# rpm -q php php-devel automake autoconf
php-5.4.16-45.el7.x86_64
未安装软件包 php-devel
未安装软件包 automake
未安装软件包 autoconf
[root@host50 opt]# yum -y install php-devel automake autoconf #安装依赖
[root@host50 opt]# tar -zxf php-redis-2.2.4.tar.gz #安装扩展包
[root@host50 opt]# cd phpredis-2.2.4/
[root@host50 phpredis-2.2.4]# ls
arrays.markdown CREDITS mkdeb.sh redis_array_impl.c serialize.list
common.h debian package.xml redis_array_impl.h tests
config.h debian.control php_redis.h redis.c
config.m4 library.c README.markdown redis_session.c
config.w32 library.h redis_array.c redis_session.h
COPYING mkdeb-apache2.sh redis_array.h rpm
[root@host50 phpredis-2.2.4]# phpize #生成配置文件php-config及configure命令
Configuring for:
PHP Api Version: 20100412
Zend Module Api No: 20100525
Zend Extension Api No: 220100525
[root@host50 phpredis-2.2.4]# ./configure --with-php-config=/usr/bin/php-config
[root@host50 phpredis-2.2.4]# make && make install
Installing shared extensions: /usr/lib64/php/modules/
[root@host50 phpredis-2.2.4]# ls /usr/lib64/php/modules/
curl.so fileinfo.so json.so phar.so redis.so zip.so
调用模块
修改php.ini文件
[root@host50 phpredis-2.2.4]# vim +728 /etc/php.ini
728 extension_dir = "/usr/lib64/php/modules" #模块文件目录
729 ; On windows:
730 extension="redis.so" #模块文件名
[root@host50 phpredis-2.2.4]# systemctl restart php-fpm //重启php-fpm服务
[root@host50 phpredis-2.2.4]# php -m | grep -i redis //查看已加载的模块
redis
测试配置
查看192.168.4.50主机的redis服务是否运行
[root@host50 ~]# netstat -utnlp | grep redis-server
tcp 0 0 192.168.4.50:6350 0.0.0.0:* LISTEN 11523/redis-server
[root@host50 ~]# redis-cli -h 192.168.4.50 -p 6350 -a 123456 //访问服务
192.168.4.50:6350> ping
PONG
192.168.4.50:6350> exit
编写PHP脚本测试
[root@host50 phpredis-2.2.4]# vim /usr/local/nginx/html/x.php
<?php
$redis = new redis();
$redis-> connect("192.168.4.51","6351");
$redis-> auth("123456");
$redis-> set("tian" , "haha");
echo OK ;
?>
在redis服务器查看数据
[root@host50 phpredis-2.2.4]# curl http://localhost/x.php #访问Nginx服务
OK
[root@host51 ~]# redis-cli -h 192.168.4.51 -p 6351 -a 123456 #连接redis服务
192.168.4.51:6351> keys * #查看变量
1) "x"
2) "tian"
192.168.4.51:6351> get tian #获取值
"haha"
总结
redis相对于MySQL的优缺点
- redis主要用来做缓存,他有持久化,但也只是为了缓存的可靠性。redis是一种内存数据库,最大的优点在于数据全放在内存,速度快,效率高。尤其是在某些特定的场合,比如热点的数据量非常大,而数据在内存和磁盘之间切换代价比较高的场景下,适合应用redis
- redis主要的缺点是数据不能超过内存大小。传统关系型数据库在于它对于数据库的一致性保障,它的数据模型范式是遵循严格事物规则的结构化数据,由于其数据的高度抽象画,它调度到内存的数据一般场合不会占用很大的内存空间。redis和MySQL各自有不同的业务场景,谁都无法取代
redis数据类型
- string字符类型
- 常用命令
- get、set、incr、decr、mget等
- Hash数列类型
- 常用命令
- hget、hset、hgetall
- List列表类型
- 常用命令
- ipush、rpush、lpop、rpop、lrange、BLPOP(阻塞版)等
- Set集合类型
- 常用命令
- sadd、srem、spop、sdiff、smembers、sunion等
- Sorted set 有序集合类型
- 常用命令
- zadd、zrange、zrem、zcard等
redis应用领域
- 缓存(数据查询、短连接、新闻内容、商品内容等)
- 分布式集群架构中的session分离
- 聊天室的在线好友列表
- 任务队列(秒杀、抢购、12306等)
- 应用排行榜
- 网站访问统计
- 数据过期处理(可以精确到毫秒)