not only SQL,非关系型数据库,它能解决常规数据库的并发,如传统的数据库的IO与性能的瓶颈,一样也是关系型数据库的一个补充,有较好的高效率与高性能。php
一、解决如下问题:前端
1)对数据库的高并发读写需求
2)大数据的高效存储和访问需求
3)高可扩展性和高可用性的需求
二、Nosql数据库的应用环境python
1)数据模型比较简单
2)须要灵活性更强的IT系统
3)对数据库的性能要求较高
4)不须要高度数据一致性
5)对于给定KEY,比较容易映射复杂值的环境mysql
三、Nosql软件的分类与特色git
1)key-value键值存储数据库(redis、memcached、ttserver) 可经过key来添加、查询、删除数据github
1.用于内容缓存,适合负载并扩展大的数据集redis
2.数据类型是一系列的键值对算法
3.有快速查询功能,但存储数据少结构化sql
4.对事务的支持很差,数据库故障产生时不可进行回滚数据库
适用场景:存储用户信息,如会话、配置文件、参数、购物车、计数(统计粉丝关注)等
2)列存储数据库(HBase) 查询多个列
1.用于分布式的文件系统
2.以列簇式存储,将同一列数据存在一块儿
3.查找速度快,可扩展强,更容易进行分布式扩展
4.功能相对局限
适用场景:日志(将信息写入本身的column family中);blog平台(存储到不一样的column family中,如标签、类别、文章等);
3)面向文件的数据库(mongoDB) 版本化的文档,半结构化的文档
1.用于WEB应用较多
2.数据类型是一系列键值对
3.查询性能不高,没有统一的查询语法
适用场景:日志(程序有不一样的日志);无固定的模式,存储不一样的信息;分析(不改变模式就可存储不一样的度量方法及添加新的度量)
4)图形数据库(Graph) 数据已图的方式存储
1.社交网络应用较多
2.不容易作分布式的集群方案
经常使用的Nosql数据库介绍
适用场景:在关系型强的数据中;推荐引擎,若将数据以图的形式表现,会很是有益于推荐的制定
四、经常使用的Nosql数据库介绍
1)memcached
是一个开源高性能的,具备分布式内存对象的缓存系统
特色:
一、安装布署简单
二、支持高并发、高性能
三、经过程序或负载均衡能够实现分布式
四、仅为内存缓存,重启服务数据丢失
2)memcacheDB
是新浪基于memcached开发的一个开源项目,具有了事务恢复功能
特色:
一、高并发读写
二、高效存储
三、高可用数据存储
3)ttserver(tokyo tyrant/tokyocabinet)
是日本人开发的一款DBM数据库,该DB的rw很是快,是BDB的几倍,哈希模式写入100万条数据只需0.643s,读100万条数据只需0.773s
特色:
一、不但支持内存缓存还可持久化存储;
二、故障转移,tokyo tyrant支持主从模式,也支持双机互为主从模式,主从库都可rw;
三、5KW条数据级别内的访问至关快;
四、兼容memcached协议,客户端不需更改任何代码;
4)mongoDB(document-oriented)
是一个基于分布式文件存储的数据库。由C++语言编写
特色(易部署、高性能、易使用、存储数据很是方便);
5)redis(key-value)
是一个开源的使用ANSIC语言编写(代码3W多行)、支持网络、可基于内存亦可持久化的日志型、Key-Value数据库,并提供多种语言的API
1)支持内存缓存,至关于memcached;
2)持久化,至关于memcachedb,ttserver;
3)数据类型更丰富;
4)支持集群,分布式;
五、生产环境如何选择Nosql数据库
1)最常规的缓存应用,memcached最合适
2)持久化存储方案memcacheDB
3)2000万之内数据量的小数据用memcached
4)大数据量能够用redis
redis是一种 持久化缓存服务 ,会周期的把更新的数据写入磁盘以及把修改操做记录追加到文件里记录下来,还 支持主从同步模式 ,是一个开源的基于C语言编写的,支持网络、内存可持久化的日志型、key-value数据库
一、redis持久服务的特色
key-value键值类型存储系统
支持数据可靠存储
单进程单线程高性能服务器
恢复比较慢
单机qps(秒并发)能够达到10W
适合小数据高速读写访问
redis存储系统优、缺点:
能够持久化存储数据
支持每秒10W的读写频率
支持丰富的数据类型
全部操做都是原子性的
支持异机主从复制
内存管理开销大(低于物理内存的3/5)
不一样命令延迟差异大
二、redis持久化介绍
redis将 数据存储于内存中 ,经过 快照、日志 两种方式实现持久化存储,前者性能高,会有数据丢失的状况,后者相反。
snapshot(快照):一次性将内存中的数据写入到磁盘,或使用相似MySQL的binlog日志
aof 方式:记录每次更新的日志,不会致使数据的丢失;(不用于主从同步)仅仅用于保存数据;
#名词解释 #Snapshot(快照) save 900 1 #900秒有1key容量被更新,则触发快照写入磁盘 save 300 10 save 60 10000 #AOF(更新日志) appendfsync always #老是记录更新内容 appendfsync everysec #每秒记录更新内容 appendfsync no #不记录更新内容
若是选择了快照的策略,那么快照在每次进行保存的时候,都会阻碍执行前端的客户端请求
三、 redis的数据类型
String 字符串
Hash 哈希表
List 列表
Set 集合
Sorted set 有序集合
四、redis应用场景
1)redis所有数据在memory
2)最佳对memcached的替代品;
3)数据比较重要,对数据一致性有必定要求的业务;
4)当须要除key/value以外的更多数据类型支持时,使用redis更合适;
5)须要提供主从同步以及负载均衡分布式应用场景(redis主从同步);
6)计数,cache服务,展现最近,最热,点击率最高,活跃度最高等等条件的top list,用户最近访问记录,Relation List/Message Queue,粉丝列表
五、redis的应用案例
1)应用程序-->redis
2)应用程序首先访问Redis,只有当Redis没有数据或访问失败时访问MySQL
3)二次开发实现MySQL和redis互相同步
六、redis的生产经验教训
1)要进行master-slave主从同步配置,在出现服务故障时能够切换;
2)在master禁用数据持久化,只需在slave上配置数据持久化;
3)物理内存+虚拟内存不足,这个时候dump一直死着,时间久了机器挂掉
4)当redis物理内存使用超过内存总容量的3/5时就会开始比较危险了,就开始作swap,内存碎片大!
5)当达到最大内存时,会清空带有过时时间的key,即便key未到过时时间;
6)redis与db同步写的问题,先写db,后写redis,由于写内存基本上没有问题;
一、安装redis
wget http://download.redis.io/releases/redis-2.8.24.tar.gz tar zxf redis-2.8.24.tar.gz cd redis-2.8.24 make make PREFIX=/application/redis-2.8.24 install
二、相关命令做用
redis-server #Redis服务器的daemon启动程序 redis-cli #Redis命令操做工具。固然,你也能够用telnet根据其纯文本协议来操做 redis-benchmark #Redis性能测试工具,测试Redis在你的系统及你的配置下的读写性能。 redis-check-aof #对更新日志appendonly.aof检查,是否可用,相似检查mysql binlog的工具 redis-check-dump #用于本地数据库rdb文件的检查
三、启动服务
1、查看命令帮助 redis-server -h 2、从源程序目录复制redis.conf到安装目录 cp redis-2.8.24/redis.conf /application/redis/conf/ 3、启动服务 redis-server /application/redis/conf/redis.conf &
四、关闭服务
redis-cli shutdown
redis-cli shutdown save
启动后,会出现警告:若是内存不够的状况下后台保存可能会失败
解决方法:
1、永久生效 echo "vm.overcommit_memory = 1" >> /etc/sysctl.conf sysctl -p 2、临时生效 sysctl vm.overcommit_memory=1 vm.overcommit_memory参数说明: 0:当用户空间请求更多的内存时,内核尝试估算出剩余可用的内存。 1:当设这个参数值为1时,内核容许超量使用内存直到用完为止,主要用于科学计算 2:当设这个参数值为2时,内核会使用一个毫不过量使用内存的算法,即系统整个内存地址空间不能超过swap+50%的RAM值,50%参数的设定是在overcommit_ratio中设定。
四、相关命令
redis-cli 链接本地redis set id 001 写入一条数据 get id 取值 del id 删除 exists id 验证key是否存在 keys * 查看redis里全部的key select 1 切换到表1模式(默认有16个库,没法看到,库的数量可在redis.conf中配置)
五、redis-cli客户端的远程链接及非交互式操做数据库
redis-cli -h 10.0.0.135 -p 6379 redis-cli -h 10.0.0.135 -p 6379 set aaa 111 redis-cli -h 10.0.0.135 -p 6379 get aaa telnet 10.0.0.135 6379 echo "set no004 zsq"|nc 127.0.0.1 6379 echo "get no004 "|nc 127.0.0.1 6379
六、redis命令帮助
1)redis-cli客户端命令帮助: 10.0.0.135:6379> ? #查看帮助命令用法 10.0.0.135:6379> help #查看帮助命令用法 10.0.0.135:6379> help set #查看set命令用法 2)经过help命令来查找命令 10.0.0.135:6379> help @generic #这里须要狂按Tab键 输入help + 空格 + 屡次<Tab>键来切换全部命令
七、redis安全
1)设置密码
redis没有用户的概念,客户端能够在1秒内进行上万次的密码尝试,要设置强大的密码来防止暴力破解 339:# requirepass 密码 redis-cli shutdown save redis-server /usr/local/redis/conf/redis.conf & 第一种登录验证方式 redis-cli auth yunjisuan 提交验证密码 keys * 查看全部keys 第二种登陆验证方式 redis-cli -a 密码 登录时提交密码
2)将危险的命令更名
1、修改配置文件 359 rename-command set "sset"
2、重启redis进程 redis-cli -a 密码 shutdown redis-server /usr/local/redis/conf/redis.conf &
3、验证命令更名效果 redis-cli -a 密码 sset xxx 555 写入key-value正确 get xxx
4、其余 rename-command set "" 好比屏蔽这个set
八、为php安装redis客户端扩展
1)获取源码包 wget https://github.com/nicolasff/phpredis/archive/master.zip 2)安装 unzip phpredis-master.zip cd phpredis-master /application/php/bin/phpize ./configure --with-php-config=/application/php/bin/php-config make && make install 3)检查 ls /application/php-5.6.8/lib/php/extensions/no-debug-non-zts-20131226/ memcache.so opcache.a opcache.so redis.so 4)修改php.ini设置,重启php echo "extension = redis.so" >> /application/php/lib/php.ini #将php.ini配置文件中的extension_dir修改为以下: extension_dir = "/application/php-5.6.8/lib/php/extensions/no-debug-non-zts-20131226/"
killall php-fpm
/application/php/sbin/php-fpm
九、php程序实战操做redis服务
必需要有php环境 cat /application/php/bin/php 1.php <?php $redis = new Redis(); $redis ->connect('192.168.179.162',6379); $redis ->auth('zsq'); $redis ->set('name','zsq'); $var = $redis ->get('name'); echo "$var\n"; ?>
十、安装Python redis客户端操做redis
wget https://pypi.python.org/packages/source/r/redis/redis-2.10.1.tar.gz tar xf redis-2.10.1.tar.gz cd redis-2.10.1 python setup.py install
开发python程序操做redis
# python >>> import redis #引用redis支持库 >>> r = redis.Redis(host='10.0.0.135',port='6379',password='yunjisuan') #创建redis数据库的链接对象(面向对象方式) >>> r.set('name','benet') #操做对象调用set方法写入数据 >>> r.get('name') #操做对象调用get方式读取数据 >>> r.dbsize() #操做对象查看redis数据库的数据条数 >>> r.keys() #查看全部的key>>> exit() #退出
经过Web界面链接Python程序展现redis
# cat python-redis.py #/usr/bin/python from wsgiref.simple_server import make_server import redis def get_redis(): r = redis.Redis(host='10.0.0.135',port='6379',password='yunjisuan',db=0) r.set('name','yunyunyun') return r.get('name') def hello_world_app(environ,start_response): status = '200 OK' #HTTP Status headers = [('Content-type','text/plain')] #HTTP Headers start_response(status,headers) # The returned object is going to be printed return get_redis() httpd = make_server('',8000,hello_world_app) print "Serving on port 8000..." # Server until process is killed httpd.serve_forever()
启动python脚本
# python python-redis.py Serving on port 8000... #监听8000端口 经过客户端浏览器链接Python程序 127.0.0.1:8000
十一、解读redis默认配置文件
#redis支持include功能
30 include /path/to/local.conf
31 include /path/to/other.conf
#redis是否后台运行
37 daemonize no
#pid号保存文件的位置
41 pidfile /var/run/redis.pid
#redis默认监听端口
45 port 6379
#调整tcp监听队列
54 tcp-backlog 511
#调整redis的监听地址
63 bind 192.168.1.100 10.0.0.1
64 bind 127.0.0.1
#调整客户端超时时间
74 timeout 0
#调整tcp的会话保持时间
90 tcp-keepalive 0
#调整日志级别
98 loglevel notice
#redis日志记录位置,默认是打印到屏幕上
103 logfile ""
#是否启用syslog来接收日志(好比日志集中收集)
113 syslog-facility local0
#设置数据库的数量,若是缺省,默认为0(select0...select 15)
118 databases 16
#redis快照设置
140 #save "" #若是不想保存在磁盘,就如此设置
142 save 900 1 #900秒内至少1key数据变化,但会阻塞用户请求,高并发时不用
143 save 300 10 #300秒内至少10key数据变化,但会阻塞用户请求,高并发时不用
144 save 60 10000 #60秒内至少10000key数据变化,但会阻塞用户请求,高并发时不用
#若是bgsave出错是否中止写入
159 stop-writes-on-bgsave-error yes
#redis将数据存储在磁盘的什么位置
177 dbfilename dump.rdb
#指定redis配置文件当前工做的路径(指定dbfilename的当前路径位置)
187 dir ./
#给redis设定密码
339 requirepass 123456
#修改redis操做命令的名称
355 rename-command CONFIG ""
356 rename-command set ""
357 rename=command get wk
#设定redis内存限制(可是内存用完后,redis就会开始删除key)
398 maxmemory <bytes>
#设定redis内存清理的算法
403 # volatile-lru -> remove the key with an expire set using an LRU algorithm
404 # allkeys-lru -> remove any key accordingly to the LRU algorithm
405 # volatile-random -> remove a random key with an expire set
406 # allkeys-random -> remove a random key, any key
407 # volatile-ttl -> remove the key with the nearest expire time (minor TTL)
408 # noeviction -> don't expire at all, just return an error on write operation
#设定redis内存限制及内存清理的算法示例
421 maxmemory-policy volatile-lru
#是否启用AOF存储模式
451 appendonly no
#设定AOF文件的存储位置
455 appendfilename "appendonly.aof" #并不用于主从同步,只是redis在启动时,读取此文件用于恢复数据
#设定AOF同步存储的时间周期
481 appendfsync everysec #每秒或不用
#自动保持rewrite
522 auto-aof-rewrite-percentage 100
523 auto-aof-rewrite-min-size 64mb
#lua脚本实现更多生产场景
541 lua-time-limit 5000
#hash优化参数
hash-max-ziplist-entries 512
hash-max-ziplist-value 64
key建议:长度10到20
value建议:String 不要超过2k,集合和有序集合不要超过5k
Redis支持五种数据类型string(字符串),hash(哈希),list(列表),set(集合)及zset(sorted set:有序集合)。
一、String字符串类型
string是redis最基本的类型,一个key对应一个value,string类型是二进制安全的,包含任何数据,但值的长度不能超过1GB
1)String类型也能够用来存储数字,并支持对数字的加减操做:
set id 1 #设置键为id 值为1 get id #查数据 incr id #自动自增长1 incrby id 5 #自动自增指定数值 decr id #自动自减1 decrby id5 #自动自减指定数值
2)为key设置新值而且返回原值
getset user01 wangwu #设置新数据并返回旧数据 get user01
3)String类型还支持批量读写操做
mset name zhangsan age 44 mget name age
4)string类型还支持对其部分的修改和获取操做
append images .jpg #追加字符串 strlen images #计算字符串长度 substr images 0 6 #取0到6的值
5)命令使用帮助
#查看单个命令help+命令名 help set #查看字符串全部命令 help @string
二、List类型
Redis 列表是简单的字符串列表,按照插入顺序排序。你能够添加一个元素导列表的头部(左边)或者尾部(右边)。
lpush students "zhangsan" #将元素“zhangsan”放在students列表的最左边 lpush students "wangwu" #将元素“wangwu”插入列表的最左边 lrange students 0 1 #查看序列是0到1的元素 rpush students "wangyue" #将元素wangyue插入列表的最右边 llen students #查看列表元素的个数 lpop students #移除最左边的元素值 rpop students #移除最右边的元素值 lrem students 2 "zhangsan" #删除列表里是“zhangsan”的元素,删除两次(从左向右删) lrem students 1 "zhangsan" #删除列表里的元素zhangsan一次 lrem students 0 "zhangsan" #清空列表全部的zhangsan元素 linsert students before b xxxx #在元素b的前边插入元素xxxx linsert students after b xxxx #在元素b的后边插入元素xxxx 更多操做,请查询help @list
list可实现聊天系统。还能够做为不一样进程间传递消息的队列。
三、集合(Sets)类型
Redis的Set是string类型的无序集合,集合内的元素具备惟一性,集合是经过哈希表实现的,因此添加,删除,查找的复杂度都是O(1)。
sadd users laoda #向集合users里添加一个元素“laoda”
sadd users laoer laosan #向结合users里添加两个元素laoer,laosan
smembers users #查看集合里的全部元素(看到集合里的元素是无序的)
sismember users laoda #查看元素laoda是否存在于集合users中
###更多操做,请查询help @set
四、有序集合(Sorted Sets)类型
redis经过分数来为集合中的成员进行从小到大的排序。
#向一个有序集合里添加元素 zadd hackers 1940 "1940-Alan Kay" #hackers是有序集合名,1940是序号,1940-Alan Kay是值 zadd hackers 1969 "1969-Linus Torvalds" zadd hackers 1912 "1912-Alan Turing" #ZADD建立的集合是有序集合。 zrange hackers 0 6 #查看集合索引0到6的元素 zrevrange hackers 0 -1 #利用zrevrange进行反向查询 #查看有序集合days的具体值的排序 zscore hackers "1969-Linus Torvalds"
zscore hackers -inf 1912 #负无穷到1912之间的值
zscore hackers 1912 1940 #1912到1960之间的值
###更多操做,请查询help @sorted_set
五、Hash类型
Redis可以存储key对多个属性的数据(好比user1,uname user1.passwd)
#存储一个hash类型test,他的属性是name,属性数据是yunjisuan hset test name yunjisuan #存储一个hash类型test,他的属性是age,属性数据是35 hset test age 35 #存储一个hash类型test,他的属性是sex,属性数据是non hset test sex nan #查看hash类型test的全部属性的值 hvals test #查看hash类型test的全部属性及属性所对应的值 hgetall test
一、建立redis多实例的存储目录及文件
#建立redis多实例存储目录 mkdir -p /data/6380/data mkdir -p /data/6381/data #建立redis多实例配置文件 cp /usr/local/redis/conf/redis.conf /data/6380/ cp /usr/local/redis/conf/redis.conf /data/6381/ #修改多实例的数据存储路径 sed -n '187p' /data/6380/redis.conf dir /data/6380/data sed -n '187p' /data/6381/redis.conf dir /data/6381/data #修改多实例的占用端口 sed -n '45p' /data/6380/redis.conf port 6380 sed -n '45p' /data/6381/redis.conf port 6381 #修改多实例的pid文件位置 sed -n '41p' /data/6380/redis.conf pidfile /data/6380/redis.pid sed -n '41p' /data/6381/redis.conf pidfile /data/6381/redis.pid #开启多实例的持久化日志 sed -n '449p' /data/6380/redis.conf appendonly yes sed -n '449p' /data/6381/redis.conf appendonly yes
二、启动redis多实例
redis-server /data/6380/redis.conf & redis-server /data/6381/redis.conf &
三、查看redis多实例的进程启动状况
netstat -antup | grep redis
四、查看多实例文件夹目录树一览
# tree /data /data ├── 6380 #redis实例6380启动目录 │ ├── data #redis实例6380数据目录 │ │ ├── appendonly.aof #redis实例6380的数据持久化日志(记录了数据库的修改,相似binlog) │ │ └── dump.rdb #redis实例6380数据存储文件 │ └── redis.conf #redis实例6380配置文件 └── 6381 ├── data │ ├── appendonly.aof │ └── dump.rdb └── redis.conf
appendonly.aof:记录咱们对redis数据库的修改记录,这点相似于MySQL的binlog日志。
一、Redis主从同步特色
a、一个master能够拥有多个slave
b、多个slave能够链接同一个master,还能够链接到其余slave
c、主从复制不会阻塞master,在同步数据时,master能够继续处理client请求。
d、提升系统的伸缩性
二、Redis主从同步的过程
a、Slave服务器链接到Master服务器
b、Slave服务器发送SYNC命令
c、Master服务器备份数据库到.rdb文件
d、Master服务器把.rdb文件传输给Slave服务器
e、Slave服务器把.rdb文件数据导入到数据库中
三、Redis的主从同步具备明显的分布式缓存特色:
1)一个master能够有多个slave,一个slave下面还能够有多个slave
2)slave不只能够链接到master,slave也能够链接其余slave造成树状。
3)主从同步不会阻塞master,可是会阻塞slave。当一个或多个slave与master进行初次同步数据时,master能够继续处理client发来的请求。相反slave在初次同步数据时则会阻塞不能处理client的请求。
4)主从同步能够同来提升系统的可伸缩性,咱们能够用多个slave专门处理client端的读请求,也能够用来作简单的数据冗余或者只在slave上进行持久化从而提高集群的总体性能。
5)对于老版本的redis,每次重连都会从新发送全部数据
四、Redis主动同步设置方法
有两种方式:
1)命令方式(临时生效)
redis-cli slaveof no one #中止主从同步 redis-cli slaveof 192.168.1.100 6379 #启动主从同步
2)修改配置文件(永久)
1、修改配置文件 vim /data/6380/redis.conf slaveof 192.168.0.135 6379 #指定主master的IP和端口 masterauth yunjisuan #指定验证的密码 2、重启redis的服务 redis-cli -p 6380 -a yunjisuan shutdown #关闭6380redis进程 redis-server /data/6380/redis.conf & #后台启动
当再次启动从库时出现以下信息:
* Connecting to MASTER 192.168.0.135:6379 #链接master * MASTER <-> SLAVE sync started #开始发送sync * Non blocking connect for SYNC fired the event. #这是一个不阻塞事件 * Master replied to PING, replication can continue... #master应答了ping,同步开始 * Partial resynchronization not possible (no cached master) #从新进行同步不可能(master没有缓存内容) * Full resync from master: #从master同步所有数据 * MASTER <-> SLAVE sync: receiving 49 bytes from master #从master接收到49字节数据 * MASTER <-> SLAVE sync: Flushing old data #刷新旧数据 * MASTER <-> SLAVE sync: Loading DB in memory #数据放到内存 * MASTER <-> SLAVE sync: Finished with success #同步完成 * Background append only file rewriting started by pid 3620 #AOF重写 * Background AOF rewrite terminated with success #AOF重写成功
* Background AOF rewrite finished successfully #AOF重写完毕
redis主从同步测试
redis-cli -a yunjisuan -p 6380 get name #获取redis6380的键name的值 redis-cli -a yunjisuan -p 6380 monitor #监听主服务写入操做 redis-cli -a yunjisuan -p 6379 set name xxxxx #向redis6379里存一个key=name,value=tom的数据 redis-cli -a yunjisuan -p 6380 get name #获取redis6380的键name的值
redis主从同步相关配置参数解释
slaveof 192.168.0.135 6379 #用于标识master的链接IP及端口号 masterauth yunjisuan #master端链接密码 slave-serve-stale-data yes #从库链接不上主库,设置yes,从库依然正常提供服务,但内容有多是过时的。设置no,不提供服务,slave会应答一个错误提示 slave-read-only yes #从库被设置为只能读 repl-ping-slave-period 10 #每10秒发送ping,到master端 repl-backlog-size 1mb #用于同步的backlog大小,用于从库增量同步 repl-backlog-ttl 3600 #当主从链接断开,backlog的生存周期 slave-priority 100 #slave的优先级
查看redis各项参数的方法
redis-cli -a yunjisuan -p 6379 #登录 127.0.0.1:6379> info #查看各项信息 127.0.0.1:6379> info cpu #查看CPU信息 127.0.0.1:6379> info clients #查看客户端信息
127.0.0.1:6379> info replication #查看同步信息 role:master #本redis是主 connected_slaves:1 #链接从服务的数量 slave0:ip=192.168.0.135,port=6380,state=online,offset=11972,lag=1 #从库ip,端口,状态,偏移量等
一、redis的订阅功能
pub/sub,发布/订阅是一种消息通讯模式,主要目的解耦消息发布者和消息订阅者之间的耦合,也解决二者在物理部署上的耦合,与设计模式中的观察者模式相似;
redis可将数据推到某个信息管道中,其它人可经过订阅这些管道来获取推送过来的消息;
#开启redis的订阅功能(一个窗口) 127.0.0.1:6379> subscribe yunjisuan #开启频道名:yunjisuan的订阅功能
127.0.0.1:6379> subscribe yunjisuan* #可开启多个窗口进行订阅 #对频道进行内容推送 只要在推送端推送,订阅端就能看到(同台机器,另个窗口) 127.0.0.1:6379> publish yunjisuan 'welcome' #向频道yunjisuan推送welcome (integer) 2 #推送成功的人数 127.0.0.1:6379> publish yunjisuan '很高兴' 更多 help @pubsub
二、redis数据过时设置及过时机制
redis对过时key采用了lazy expiration,两种方式:passive way(在访问key时断定key是否过时,若是过时则进行过时处理);active way(每秒对volatile keys进行抽样测试,若是有过时key,将对全部过时key进行处理);
127.0.0.1:6379> expire name 5 #给key name设置5秒过时时间 127.0.0.1:6379> TTL name #查看key过时时间(-1为永久不过时,-2为已通过期) 127.0.0.1:6379> get name #过时了的key是没法经过key获取value的
更多 help @generic
过时的key没有被访问可能不会被删除
三、事务性
redis支持简单的组合型的命令,例如以nx结尾的命令用于判断key所对应的value没有时也进行某个命令;
127.0.0.1:6379> setnx name #当key的值不存在时,设置key的值 127.0.0.1:6379> set name tom #设置一个key,值为tom 127.0.0.1:6379> get name #查看key的值 127.0.0.1:6379> multi #开始提交事务 127.0.0.1:6379> set name a #(当事务中有错误时将都不执行) 127.0.0.1:6379> set name b #(当事务中有错误时将都不执行) 127.0.0.1:6379> exec #(执行以上事务,discard为取消事务)
四、redis持久化
redis支持两种持久化方式,一种是Snapshotting(快照)也是默认方式,另外一种是Append-only file(缩写aof)的方式。
1)数据快照
将内存中数据以快照的方式写入到二进制文件中,默认的文件名为dump.rdb,若redis意外挂掉则会丢失最后一次快照的全部修改。
#与rdb相关的配置文件信息 dir /data/redis/ #dir为rdb存储的路径 dbfilename dump.rdb #rdb存储文件的名字 save 900 1 #900 秒内若是超过1个key被修改,则发起快照保存 save 300 10 #300 秒内若是超过10个key被修改,则发起快照保存 save 60 10000 #60 秒内若是超过10000个key被修改,则发起快照保存 rdbcompression no #rdb压缩最好关闭,影响cpu
快照保存过程:
a、redis调用fork,如今有了子进程和父进程
b、父进程处理client请求,子进程将内存内容写入到临时文件。因为Linux的写时复制机制(copy on write)父子进程会共享相同的物理页面,因此子进程的数据是fork时的一个快照。
c、当子进程将快照写入临时文件完毕后,用临时文件替换原来的快照文件,而后子进程退出。
注:client能够用save、bgsave命令通知redis作一次快照持久化。
save操做是在主线程中保存快照的,因为redis是用一个主线程来处理全部client的请求,这种方式会阻塞全部client请求。因此不推荐使用。bgsave开启一个子进程所以不会阻塞。
每次快照持久化都是将内存数据完整写入到磁盘一次,并非增量的同步变动数据。若是数据量大,且写操做比较多,会引发大量的磁盘io操做,会严重影响性能。
数据快照的原理是将整个Redis中存的全部数据一遍一遍的存到一个扩展名为rdb的数据文件中。经过SAVE命令能够调用这个过程。
redis关闭时,redis自动进行RDB文件的保存 启动时会读取RDB文件.若是没有找到RDB文件则数据丢失.
设置开启或者关闭rdb存储
方法一: 修改配置文件 vim /usr/local/redis/conf/redis.conf save "" #关闭rdb save 60 10000 #开启rdb save 300 10 save 900 1 方法二: 在线修改配置,不用重启服务 redis-cli config set save "" #关闭rdb存储 redis-cli config rewrite #配置保存 redis-cli config set save "180 1 120 10 60 10000" #开启rdb redis-cli config rewrite #配置保存
进行有rdb文件的数据还原测试
redis-cli -a yunjisuan set names john #向redis里写入一个键值对 redis-cli -a yunjisuan get names #查看键的值 ll --full-time /usr/local/redis/data/ #此时/usr/local/redis/data目录下没有任何东西
redis-cli -a yunjisuan shutdown #关闭redis进程
* Saving the final RDB snapshot before exiting. #关闭时,redis自动进行RDB文件的保存 * DB saved on disk #RDB文件已经保存到了磁盘上
ll --full-time /usr/local/redis/data/ #此时目录下已经生成了RDB快照 redis-server /usr/local/redis/conf/redis.conf & #后台启动redis redis-cli -a yunjisuan get names #查询redis中的键值对
2)Append-Only File(追加式的操做日志)
redis会将收到的写命令都经过write函数追加到文件中,默认是appendonly.aof,当redis重启时会从新加载这个文件,用以在内存中重建整个DB;
相似MySQL的binlog日志方式,记录每次对DB有变化的操做
有三种方式以下(默认是:每秒fsync一次)
appendonly yes #启用aof持久化方式 no关闭
appendfsync always #收到写命令就当即写入磁盘,最慢,可是保证彻底的持久化
appendfsync everysec #每秒钟写入磁盘一次,在性能和持久化方面作了很好的折中
appendfsync no #彻底依赖os,性能最好,持久化没保证
aof引起的问题
假如咱们调用incr test命令100次,文件中必须保存所有的100条命令,其实有99条都是多余的,为了压缩aof的持久化文件。redis提供了bgrewriteaof命令,优化aof文件
开启bgrewriteaof重写的方式
1、命令测试 127.0.0.1:6379> set num 1 #设置一个key,值是1 127.0.0.1:6379> incr num #自动加1 127.0.0.1:6379> incr num cat appendonly.aof #优化前,全部命令都保存 127.0.0.1:6379> bgrewriteaof #启动优化命令 cat appendonly.aof #优化后,保存
2、修改配置文件,自动优化 449 appendonly yes #修改本行内容开启AOF 520 auto-aof-rewrite-percentage 100 #当100%达到最小大小的时候才会执行重写 521 auto-aof-rewrite-min-size 64mb #自动重写aof文件的最小大小
aof保存过程
一、redis调用fork,如今有父子两个进程
二、子进程根据内存中的数据库快照,往临时文件中写入重建数据库状态的命令。
三、父进程继续处理client请求,除了把写命令写入到原来的aof文件中。同时把收到的写命令缓存起来.这样就能保证若是子进程重写失败的话并不会出问题。
四、当子进程把快照内容写入已命令方式写到临时文件中后,子进程发信号通知父进程。而后父进程把缓存的写命令也写入到临时文件。
五、如今父进程可使用临时文件替换老的aof文件,并重命令名,后面收到的写命令也开始往新的aof文件中追加。
重写aof文件的操做:并无读取旧的aof文件,而是将整个内存中的数据库内容用命令的方式重写了一个新的aof文件
一、经常使用命令
flushdb #清空当前库 flushall #清空全部库 config get * #查看当前配置信息 config set appendonly yes #在线修改 redis-benchmark -h localhost -p 6379 -c 100 -n 10000 #100个并发,一万次
二、内存优化
redis hash在value内部是一个hash map,若该map的成员数较少,则会采用相似一堆线性紧凑格式来存储该map,即省去了大量指针的内存开销;
hash-max-zipmap-entries 64 #当value这个map内部不超过多少个成员时会采用线性紧凑技术,默认64,超过该值自动转为hash map方式; hash-max-zipmap-value 512 #当value这个map内的每一个成员值长度不超过多少个byte就会采用线性紧凑格式存储来节省空间;
list-max-ziplist-value 64 #list数据类型节点值大小小于多少字节会采用紧凑存储格式
list-max-ziplist-entries 512 #list数据类型多少节点如下会采用去指针的紧凑存储格式
set-max-intset-entries 512 #set数据类型内部数据若是所有是数值型,且包含多少节点如下会采用紧凑格式存储
activerehashing yes #是否激活重置哈希
redis优化总结:
一、根据业务须要选择合适的数据类型,并为不一样的应用场景设置相应的紧凑存储参数;
二、当业务场景不须要数据持久化时,关闭全部的持久化方式可得到最佳的性能和最大的内存使用量;
三、若须要使用持久化,根据是否能够容忍重启后丢失部分数据,在snapshot和aof,这二者中选其一,不要使用虚拟内存vm及disk store方式(diskstore已obsolete),每秒实时写入AOF文件
四、尽可能不要让redis超过占总内存的60%;
五、redis.conf中maxmemory,是告诉redis当使用了多少物理内存后就开始拒绝后续的写入请求,该参数能很好的保护redis不会由于使用了过多的物理内存而致使swap,最终严重影响性能开始不稳定甚至崩溃;vm-enabled设置为no
六、大数据量尽可能按业务使用多个redis instance把数据分散开