NoSQL简介
- NoSQL,全名为Not Only SQL,指的是非关系型的数据库
- 随着访问量的上升,网站的数据库性能出现了问题,于是nosql被设计出来
优点/缺点
- 优点:
- 高可扩展性
- 分布式计算
- 低成本
- 架构的灵活性,半结构化数据
- 没有复杂的关系
- 缺点:
- 没有标准化
- 有限的查询功能(到目前为止)
- 最终一致是不直观的程序
Redis简介
Redis数据库采用的是key-value存储,所以它没有查询功能,它是通过key来查找value值。一般来说,存储不管value的格式,照单全收。
安装:
下载:猛击这里
解压:
tar zxvf redis-3.2.5.tar.gz
复制:推荐放到usr/local目录下
sudo mv -r redis-3.2.3/* /usr/local/redis/ 进入redis目录 cd /usr/local/redis/
生成,测试,安装:
sudo make && sudo make test && sudo make install
运行:
启动服务器:在桌面目录
redis-server 按ctrl+c停止
启动客户端:在新终端中运行如下代码
redis-cli
运行命令
ping set 'a' '123'
当添加键值后,发现在当前运行的目录下,创建了一个文件:dump.rdb,这个文件用于将数据持久化存储
配置文件:
在源文件/usr/local/redis目录下,文件redis.conf为配置文件
bind 127.0.0.1 # 绑定地址:如果需要远程访问,可将此行注释 port 6379 # 端口,默认为6379 # 表示啥时候进行写操作 save 900 1 # 900s进行了1次操作,执行一次写操作 save 300 10 # 300s进行了10次操作,执行一次写操作 save 60 10000 # 60s进行了10000次操作,执行一次写操作 databases 16 # 默认有16个数据库,名称是以0-15命名,使用select 15 命令切换数据库 daemonize no|yes # 是否以守护进程运行 # 如果以守护进程运行,则不会在命令行阻塞,类似于服务 # 如果以非守护进程运行,则当前终端被阻塞,无法使用 # 推荐改为yes,以守护进程运行 dbfilename dump.rdb # 数据文件 dir ./ # 数据文件存储路径,dir的默认值为./,表示当前目录,推荐改为:dir /var/lib/redis
一、基本数据操作
redis是key-value的数据,所以每个数据都是一个键值对
键的类型是字符串
值的类型分为五种:
- 字符串string
- 哈希hash
- 列表list
- 集合set
- 有序集合zset
数据操作的全部命令,可以查看中文文档:猛击这里
1、字符串(string类型)
- string是redis最基本的类型,也是最常用的类型
- 最大能存储512MB数据
- string类型是二进制安全的,即可以为任何数据,比如数字、图片、序列化对象等
操作
设置 set key value # 设置键值 例:set k1 v1 SETEX key seconds value # 设置键值及过期时间,以秒为单位 例:setex k2 2 v2 # 方法 键 超时时间 值 MSET key value [key value ...] # 设置多个键值 例:mset k3 v3 k4 v4 # 方法 键 值 键 值 获取 GET key # 根据键获取值,如果不存在此键则返回nil 例:get k1 >> "v1" get k2 >> (nil) 因为k2对应的值过了超时时间 MGET key [key ...] # 根据多个键获取多个值 例:mget k1 k3 >> 1) "v1" 2) "v3" 运算 INCR key # 将key对应的value加1,要求:值是数字 例: 127.0.0.1:6379> set k5 10 OK 127.0.0.1:6379> incr k5 (integer) 11 INCRBY key increment # 将key对应的value加整数 例:incrby k5 10 >> (integer) 21 DECR key # 将key对应的value减1 DECRBY key decrement # 将key对应的value减整数 其它 APPEND key value # 追加值 例: 127.0.0.1:6379> append k1 v10086 (integer) 8 127.0.0.1:6379> get k1 "v1v10086" STRLEN key # 获取值的位数 例: 127.0.0.1:6379> STRLEN k2 # 已经超时了 (integer) 0 127.0.0.1:6379> STRLEN k3 # "v3" (integer) 2
键命令
KEYS pattern # 查找键,参数支持正则 keys * # 查找全部 keys *d* # 查找正则 EXISTS key [key ...] # 判断键是否存在,如果存在返回1,不存在返回0 例: 127.0.0.1:6379> exists k1 (integer) 1 127.0.0.1:6379> exists k2 (integer) 0 TYPE key # 查看键对应的value的类型 DEL key [key ...] # 删除键及对应的值 例: 127.0.0.1:6379> del k1 (integer) 1 127.0.0.1:6379> keys * 1) "k3" 2) "k5" 3) "k4" EXPIRE key seconds # 设置过期时间,以秒为单位,创建时没有设置过期时间则一直存在,直到使用使用DEL移除 TTL key # 查看有效时间,以秒为单位
2、哈希(hash)
- hash用于存储对象,对象的格式为键值对
操作
设置 HSET key field value # 设置单个属性 例:hset k6 attr1 v1 # 键 属性 值 HMSET key field value [field value ...] # 设置多个属性 例:hmset k6 attr1 v1 # 键 属性1 值1 属性2 值2 获取 HGET key field # 获取一个属性的值 例:hget k6 attr1 >> "v1" HMGET key field [field ...] # 获取多个属性的值 例:hmget k6 attr1 k6 attr2 HGETALL key # 获取所有属性和值 例: 127.0.0.1:6379> hgetall k6 1) "attr1" # 属性1 2) "v1" # 值1 3) "attr2" # 属性2 4) "v2" # 值2 HKEYS key # 获取所有的属性 HLEN key # 返回包含属性的个数 HVALS key # 获取所有值 其它 HEXISTS key field # 判断属性是否存在 HDEL key field [field ...] # 删除属性及值 HSTRLEN key field # 返回值的字符串长度
3、数组(list)
- 列表的元素类型为string
- 按照插入顺序排序
- 在列表的头部或者尾部添加元素
设置 LPUSH key value [value ...] # 在头部插入数据 例:lpush k7 v1 v2 v3 # 键 值1 值2 值3 RPUSH key value [value ...] # 在尾部插入数据 例:rpush k7 v4 v5 v6 # 键 值1 值2 值3 127.0.0.1:6379> lrange k7 0 -1 1) "v3" 2) "v2" 3) "v1" 4) "v4" 5) "v5" 6) "v6" LINSERT key BEFORE|AFTER pivot value # 在一个元素的前|后插入新元素 例: 127.0.0.1:6379> linsert k7 before v1 v10086 # 在键为k7对应的列表中的v1前面添加v10086 (integer) 7 127.0.0.1:6379> lrange k7 0 -1 1) "v3" 2) "v2" 3) "v10086" 4) "v1" 5) "v4" 6) "v5" 7) "v6" LSET key index value # 设置指定索引的元素值,索引是从0开始的下标,索引可以是负数,表示偏移量是从list尾部开始计数,如-1表示列表的最后一个元素 例: 127.0.0.1:6379> lset k7 2 v10010 127.0.0.1:6379> lrange k7 0 -1 1) "v3" 2) "v2" 3) "v10010" 4) "v1" 5) "v4" 6) "v5" 7) "v6" 获取 LPOP key # 移除并且返回 key 对应的 list 的第一个元素 例: 127.0.0.1:6379> lpop k7 "v3" RPOP key # 移除并返回存于 key 的 list 的最后一个元素 例: 127.0.0.1:6379> rpop k7 "v6" LRANGE key start stop # 返回存储在 key 的列表里指定范围内的元素 例: 127.0.0.1:6379> lrange k7 1 3 1) "v2" 2) "v10010" 3) "v1" 其它 LTRIM key start stop # 裁剪列表,改为原集合的一个子集 例: 127.0.0.1:6379> ltrim k8 1 3 OK 127.0.0.1:6379> lrange k8 0 -1 1) "v2" 2) "v10010" 3) "v1" LLEN key # 返回存储在 key 里的list的长度 例: 127.0.0.1:6379> llen k8 (integer) 3 LINDEX key index # 返回列表里索引对应的元素 例: 127.0.0.1:6379> lindex k8 2 "v1"
4、无序集合(set)
- 无序集合
- 元素为string类型
- 元素具有唯一性,不重复
设置 SADD key member [member ...] # 添加元素 例: 127.0.0.1:6379> sadd k10 v1 v2 v3 v4 v4 v1 (integer) 4 127.0.0.1:6379> smembers k10 # 自动去重了 1) "v3" 2) "v4" 3) "v1" 4) "v2" 获取 SMEMBERS key # 返回key集合所有的元素 SCARD key # 返回集合元素个数 例: 127.0.0.1:6379> scard k10 (integer) 4 其它 SINTER key [key ...] # 求多个集合的交集 例: 127.0.0.1:6379> sadd k11 v1 v4 v5 v6 (integer) 4 127.0.0.1:6379> sinter k10 k11 1) "v4" 2) "v1" SDIFF key [key ...] # 求某集合与其它集合的差集 例: 127.0.0.1:6379> sdiff k10 k11 # Redis中的差集是前面的集合 - 后面集合 1) "v2" 2) "v3" 127.0.0.1:6379> sdiff k11 k10 1) "v6" 2) "v5" SUNION key [key ...] # 求多个集合的合集 例: 127.0.0.1:6379> sunion k10 k11 1) "v3" 2) "v6" 3) "v2" 4) "v1" 5) "v4" 6) "v5" SISMEMBER key member # 判断元素是否在集合中 例: 127.0.0.1:6379> sismember k11 v10086 (integer) 0 127.0.0.1:6379> sismember k11 v6 (integer) 1
5、有序集合
- sorted set,有序集合
- 元素为string类型
- 元素具有唯一性,不重复
- 每个元素都会关联一个double类型的score,表示权重,通过权重将元素从小到大排序
- 元素的score可以相同
设置 ZADD key score member [score member ...] # 添加 获取 ZRANGE key start stop # 返回指定范围内的元素 ZCARD key # 返回元素个数 ZCOUNT key min max # 返回有序集key中,score值在min和max之间的成员 ZSCORE key member # 返回有序集key中,成员member的score值
二、高级功能
1、发布订阅
- 发布者不是计划发送消息给特定的接收者(订阅者),而是发布的消息分到不同的频道,不需要知道什么样的订阅者订阅
- 订阅者对一个或多个频道感兴趣,只需接收感兴趣的消息,不需要知道什么样的发布者发布的
- 发布者和订阅者的解耦合可以带来更大的扩展性和更加动态的网络拓扑
- 客户端发到频道的消息,将会被推送到所有订阅此频道的客户端
- 客户端不需要主动去获取消息,只需要订阅频道,这个频道的内容就会被推送过来
消息的格式
- 推送消息的格式包含三部分
- part1:消息类型,包含三种类型
- subscribe,表示订阅成功
- unsubscribe,表示取消订阅成功
- message,表示其它终端发布消息
- 如果第一部分的值为subscribe,则第二部分是频道,第三部分是现在订阅的频道的数量
- 如果第一部分的值为unsubscribe,则第二部分是频道,第三部分是现在订阅的频道的数量,如果为0则表示当前没有订阅任何频道,当在Pub/Sub以外状态,客户端可以发出任何redis命令
- 如果第一部分的值为message,则第二部分是来源频道的名称,第三部分是消息的内容
命令
- 订阅
SUBSCRIBE 频道名称 [频道名称 ...]
- 取消订阅,如果不写参数,表示取消所有订阅
UNSUBSCRIBE 频道名称 [频道名称 ...]
- 发布
PUBLISH 频道 消息
2、主从配置
- 一个master可以拥有多个slave,一个slave又可以拥有多个slave,如此下去,形成了强大的多级服务器集群架构
- 比如,将ip为192.168.1.10的机器作为主服务器,将ip为192.168.1.11的机器作为从服务器
- 设置主服务器的配置
bind 192.168.1.10
- 设置从服务器的配置
- 注意:在slaveof后面写主机ip,再写端口,而且端口必须写
bind 192.168.1.11
slaveof 192.168.1.10 6379
- 在master和slave分别执行info命令,查看输出信息
- 在master上写数据
set hello world
- 在slave上读数据
get hello