NoSQL是一项全新的数据库革命性运动,它是指运用非关系型数据库的存储。Nosql解决了大规模数据集合多重数据类带来的挑战,尤其是大数据应用难题。
Nosql数据库的四大分类
1,键值
tokyo
Cabinet/tyrant
Redis
Voldemort
Oracle BDB
应用场景:内容缓存,主要用于处理大量数据的高访问负载,也用于一些日志系统等等。
数据模型:key指向value的键值对,通长用hash、table来实现的
优点:查找速度快
2,列存储数据库
Cassadnra
HBase,Riak
应用场景:分布式文件系统
数据模型:以列簇式存储,将同一列的数据存储在一起。
优点:查找速度块,扩展性强,更容易进行饭呢不是扩展
3,文档型数据库
CouchDB
MongoDb
应用场景:web应用
数据模型:key-Value对应的键值对,Value为结构化的数据
优点:数据结构要求不严格,表结构可变,不需要像关系型数据库一样需要预定义表结构。
4,图形数据库:
Neo4j
InfoGrid
Infinite Graph
应用场景:社交网络,推荐系统等,专属于构建关系图谱。
数据模型:图结构
优点:利用图结构相关算法。比如最短路径寻址,N度关系查找等。
NoSQL特点
Nosql是key-value形式存储,和传统的关系型数据库不一样,不一定遵循传统 数据库的一些基本要求,比如说遵循sql标准,acid属性,表结构等等。这类数据库主要有以下特点:非关系型的,分布式,开源,水平可扩展。
1,处理超大的数据量。
2,运行在便宜的pc服务器的集群上。
3,击碎了性能瓶颈。
对数据的高并发读写
对海量数据的高效存储和访问
对数据的高扩展性和高可用性
Redis
Redis是一个开源的,先进的key-value存储,它通常被称为数据结构服务器,因为键可以包含string,hash,list,set和zset(sorted-set--有序集合)。这些数据类型都支持push/pop,add/remove及取交集并集和差集及更丰富的操作,他的操作比mysql数据库更加简化。
Redis和Memcahed类似,它支持存储的value类型相对更多,与memecached一样,为了保证效率,数据都是缓存在内存中,区别是Redis会周期性的把更新的数据写入了磁盘或者把修改操作写入追加的记录文件,并且在此基础上实现了master-slave主从同步
Redis现在很多软件上都用redis作为mysql的缓存数据库,在适当的时候与mysql同步。
Redis适用场景
在应用程序直接访问Redis数据库。
在应用程序直接访问redis,只用当redis访问失败时才访问mysql数据库
yum -y install gcc*
tar -zxvf redis-2.8.6.tar.gz
cd redis-2.8.6
make
make PREFIX=/usr/local/redis install
mkdir /usr/local/redis/etc
cp ./redis.conf /usr/local/redis/etc/
Redis的启动方式:/usr/local/redis/bin/redis-server
#不加配置文件会提示警告
修改配置文件:
vim /usr/local/redis/etc/redis.conf
daemnize on 改为
daemonize yes #后台启动 端口:6379
客户端连接:
/usr/lcoal/redis/bin/redis-cli
-h IP: 连接指定的redis服务器
-p 6379: 指定redis服务器的端口
-a 密码 使用密码登陆
-n 数据库号 指定连接那个数据库
--raw: redis支持中文存储
redis关闭
/usr/local/redis/bin/redis-cli shutdown 或者 pkill -9 redis
Redis配置文件
daemonize 如果需要后台运行,改成yes
pidfile 配置多个pid的地址,默认在/var/run/redis.pid
bind 绑定ip,设置后只接受来自该ip的请求
port 监听端口,默认为6379
timeout 设置客户端连接时的超时时间,单位为秒
loglevel 分为4级,debug、verbose、notice、warning
logfile 配置log文件地址
databases 设置数据库的个数,默认使用的数据库为0,最大为16个
save 设置Redis进行数据库镜像的频率(快照)
rdbcompression 在进行镜像备份时,是否进行压缩
dbfilename 镜像备份文件的文件名
dir 数据库镜像备份的文件放置位置
slaveof 设置数据库为其他数据库的从数据库
masterauth 主数据库连接需要的密码验证
requirepass 设置登录时需要使用密码
maxclients 限制同时连接的客户数量
maxmemory 设置redis能够使用的最大内存
appendonly 开启append only模式
ppendfsync 设置对appendonly.aof文件同步的频率
vm-enabled 是否开启虚拟内存支持
vm-swap-file 设置虚拟内存的交换文件路径
vm-max-memory 设置redis使用的最大物理内存数
vm-page-size 设置虚拟内存的页大小
vm-pages 设置交换文件的总的page数量
vm-max-threads 设置VMIO同时使用的线程数量
glueoutputbuf 把小的输出缓存存放在一起
hash-max-zipmap-entries 设置hash的临界值
activerehashing 重新hash
redis的五种数据类型:
strig,hash,list,set及zset(sorted set)
基础命令操作
添加一个name=lingyu的键值对应
> set name lingyu
> get name
"lingyu"
setnx设置key对应的值为string类型的value,如果已存在返回的值是0,nx是not extist的意思
> set name linux
> setnx name lingyu
(integer) 0
> get name
"linux"
setex设置指定键值对应的有效期
>setex age 2 age
>get age
"18"
>get age
(nil)
ttl 以秒为单位,返回给定key的剩余生存时间
127.0.0.1:6379> setex mv 22 huayu
OK
127.0.0.1:6379> ttl mv
(integer) 19
127.0.0.1:6379> ttl mb
(integer) -2
127.0.0.1:6379> ttl mv
(integer) 12
127.0.0.1:6379> ttl mv
(integer) 9
127.0.0.1:6379> ttl mv
(integer) 6
127.0.0.1:6379> ttl mv
(integer) 2
127.0.0.1:6379> ttl mv
(integer) -2
127.0.0.1:6379>
当 key 不存在时,返回 -2 。
当 key 存在但没有设置剩余生存时间时,返回 -1 。
否则,以秒为单位,返回 key 的剩余生存时间。
setrange
讲wag_linux@163.com的邮箱替换成huayu邮箱
127.0.0.1:6379> set name wag_linux@163.com
OK
127.0.0.1:6379> get name
"wag_linux@163.com"
127.0.0.1:6379> setrange name 9 huayu.com
(integer) 18
127.0.0.1:6379> get name
"wag_linuxhuayu.com"
127.0.0.1:6379>
mest
一次设置多个key的值,成功返回ok表示所有的值都已经设置,失败返回0表示没有任何值呗设置。
127.0.0.1:6379> mset key1 lamp1 key2 lamp2
OK
127.0.0.1:6379> get key
(nil)
127.0.0.1:6379> get key1
"lamp1"
127.0.0.1:6379> get key2
"lamp2"
127.0.0.1:6379>
msetnx
一次设置多个key的值,成功返回ok表示所有的值都已经设置,失败返回0表示没有人很值呗设置,但是不会覆盖已存在的key的值
127.0.0.1:6379> msetnx key3 lingyu key4 boy key5 19
(integer) 1
127.0.0.1:6379> get key3
"lingyu"
127.0.0.1:6379> get key4
"boy"
127.0.0.1:6379> get key5
"19"
127.0.0.1:6379> msetnx key6 lingyu key7 boy key5 19
(integer) 0
127.0.0.1:6379> get key6
(nil)
get 获取key对应的string值,如果key不存在返回nil
getset设置key的值,并返回key的旧值
127.0.0.1:6379> get name
"wag_linuxhuayu.com"
127.0.0.1:6379> getset name lingyu@p163.com
"wag_linuxhuayu.com"
127.0.0.1:6379> get name
"lingyu@p163.com"
getrange
获取key的值value值得子字符串
127.0.0.1:6379> get name
"lingyu@p163.com"
127.0.0.1:6379> getrange name 0 7
"lingyu@p"
127.0.0.1:6379> getrange name 0 5
"lingyu"
mget 一次获取多个key的值,如果对应key不存在则对应返回nil
127.0.0.1:6379> mget key1 key2 key3 key4 key5 key6 key7
1) "lamp1"
2) "lamp2"
3) "lingyu"
4) "boy"
5) "19"
6) (nil)
7) (nil)
incr对key的值做加加(递增)操作,并返回新的值
127.0.0.1:6379> get key5
"19"
127.0.0.1:6379> incr key5
(integer) 20
incrby
同类似incr类型,加指定值,key不存在时会设置key,并认为原来的是value0
127.0.0.1:6379> incrby key5 6
(integer) 26
127.0.0.1:6379> get key6
(nil)
127.0.0.1:6379> incrby key6 6
(integer) 6
decr对key的值做加加(递减的操作),并返回新的值
127.0.0.1:6379> decr key5
(integer) 25
127.0.0.1:6379> decr key5
(integer) 24
decrby同decr类似,加指定值,key不存在时会设置在key,并认为原来的是value是0
127.0.0.1:6379> decr key5
(integer) 23
127.0.0.1:6379> decrby key5 3
(integer) 20
append给指定的key的字符串追加value,返回新字符串的长度
127.0.0.1:6379> get key3
"lingyu"
127.0.0.1:6379> append key3 @163.com
(integer) 14
127.0.0.1:6379> get key3
"lingyu@163.com"
strlen取指定key的value值得长度
127.0.0.1:6379> get key3
"lingyu@163.com"
127.0.0.1:6379> strlen key3
(integer) 14
del删除一个已创建的key
127.0.0.1:6379> del key5
(integer) 1
127.0.0.1:6379> get key5
(nil)
Redis数据库的类型hash
hash是一个string类型的field和value的映射表,它的添加,删除操作都是0(1)平均;hash特别适合用于存储对象,相较于将对象的每个字段存成单个string类型,将一个对象存储在hash类型中会占用更少的内存,并且可以更方便存储整个对象
hset设置hash filed为指定值,如果key不存在,则先创建
127.0.0.1:6379> hset num1 name lingyu
(integer) 1
127.0.0.1:6379> hget num1 name
"lingyu
hestnx设置hash filed为指定值,如果key不存在,则先创建,如果存在则返回0
127.0.0.1:6379> hsetnx num name handsome
(integer) 1
127.0.0.1:6379> hsetnx num name hashsome
(integer) 0
hmset同时设置hash的多个field
127.0.0.1:6379> hmset num2 name wag age 18
OK
127.0.0.1:6379> hget num2 name
"wag"
127.0.0.1:6379> hget num2 age
"18"
hget获取hash表里面的某一个字段
hmget获取hash表里面的多个字段
hincrby指定的hash field加上给定值
127.0.0.1:6379> hget num2 age
"18"
127.0.0.1:6379> hincrby num2 age 5
(integer) 23
hexists测试指定的field是否存在
127.0.0.1:6379> hexists num2 age
(integer) 1
127.0.0.1:6379> hexists num2 sex
(integer) 0
hlen返回指定hash的field数量
127.0.0.1:6379> hlen num2
(integer) 2
hedl删除指定hash的field
127.0.0.1:6379> hget num2 age
"23"
127.0.0.1:6379> hdel num2 age
(integer) 1
127.0.0.1:6379> hget num2 age
(nil)
hkeys返回hash的所有的field
127.0.0.1:6379> hmset num3 name hansome age 22 sex nv
OK
127.0.0.1:6379> hkeys num3
1) "name"
2) "age"
3) "sex"
hvals返回hash所有的value
127.0.0.1:6379> hvals num3
1) "hansome"
2) "22"
3) "nv"
hgetall同时返回指定hash表中的全部field和value
127.0.0.1:6379> hgetall num3
1) "name"
2) "hansome"
3) "age"
4) "22"
5) "sex"
6) "nv"
Redis数据库的类型--list
list是一个链表结构,主要功能是push、pop、获取一个范围 内的所有的值等等,操作中key理解为链表的名字,redis的list类型的其实就是一个每个子元素都是string类型的双向链表,我们可以通过push、pop操作从链表的头部或尾部添加删除元素,这样list既可以最为栈,又可以作为队列。
lpush在key对应得list的头部添加字符串元素。
127.0.0.1:6379> lpush list1 "world"
(integer) 1
127.0.0.1:6379> lpush list1 "hello"
(integer) 2
127.0.0.1:6379> lrange list1 0 -1
1) "hello"
2) "world"
0代表从头部开始第一个元素
-1代表从尾部的第一个元素
0 -1代表list链表中所有的数据
rpush在key对应list的尾部添加字符串的元素。
127.0.0.1:6379> lrange list2 0 -1
1) "world"
2) "hello
linsert在key对应的list的特定位置前或后添加字符串
127.0.0.1:6379> rpush list3 world
(integer) 1
127.0.0.1:6379> linsert list3 before world hello
(integer) 2
127.0.0.1:6379> lrange list3 0 -1
1) "hello"
2) "world"
和before对应的有after
lset设置list中指定下标的元素值
127.0.0.1:6379> rpush list4 one
(integer) 1
127.0.0.1:6379> rpush list4 two
(integer) 2
127.0.0.1:6379> rpush list4 three
(integer) 3
127.0.0.1:6379> lrange list4 0 -1
1) "one"
2) "two"
3) "three"
127.0.0.1:6379> lset list4 0 wan
OK
127.0.0.1:6379> lrange list4 0 -1
1) "wan"
2) "two"
3) "three"
lrem从key对应list中删除n个”指定值“的元素
127.0.0.1:6379> rpush list5 hello
(integer) 1
127.0.0.1:6379> rpush list5 hello
(integer) 2
127.0.0.1:6379>
127.0.0.1:6379> rpush list5 hello
(integer) 3
127.0.0.1:6379> lrem list5 1 hello
(integer) 1
127.0.0.1:6379> lrange list 5 0 -1
(error) ERR wrong number of arguments for 'lrange' command
127.0.0.1:6379> lrange list5 0 -1
1) "hello"
2) "hello"
127.0.0.1:6379> lrem list5 0 hello
(integer) 2
127.0.0.1:6379> lrange list5 0 -1
(empty list or set)
n 代表删除“指定值”元素的数量
n > 0
从队列头向尾删除n个“指定值”元素
n < 0
从队列尾向头删除n个“指定值”元素
n = 0
删除所有值为“指定值”的元素
lpop从list的头部删除元素,并返回删除元素
lrange list 0 -1
lamp
hello
world
lpop list1
lamp
lrange list1 0 -1
hello
world
rpop从list的尾部删除元素,并返回删除元素。
rpoplpush从第一个list的尾部移除的元素添加到第二个list的头部
127.0.0.1:6379> lrange list2 0 -1
1) "world"
2) "hello"
127.0.0.1:6379> lrange list3 0 -1
1) "hello"
2) "world"
127.0.0.1:6379> rpoplpush list2 list3
"hello"
127.0.0.1:6379> lrange list3 0 -1
1) "hello"
2) "hello"
3) "world"
lindex获取队列中的指定下标元素的值
127.0.0.1:6379> lrange list4 0 -1
1) "wan"
2) "two"
3) "three"
127.0.0.1:6379> lindex list4 1
"two"
127.0.0.1:6379> lindex list4 2
"three"
llen获取队列的长度(元素个数)
Redis的数据类型--set
set类型及操作
set是集合,它是string类型的无序集合。Set是通过hash table实现的,对集合我们可以取并集、交集、差集。通过这些操作我们可以实现社交网站中的好友推荐和blog的tag功能。集合不允许有重复值。
sadd添加一个或多个元素到集合中
127.0.0.1:6379> sadd mest1 1
(integer) 1
127.0.0.1:6379> sadd mset1 2 3 4
(integer) 3
smembers获取集合里面所有的元素
127.0.0.1:6379> sadd mset1 2 3 4
(integer) 3
127.0.0.1:6379> smembers mset1
1) "2"
2) "3"
3) "4"
集合里面不能有重复的元素
srem从集合中删除指定的一个或多个元素
127.0.0.1:6379> srem mset1 2 4
(integer) 2
127.0.0.1:6379> smembers mset1
1) "3"
127.0.0.1:6379> srem mset1 2
(integer) 0
删除键,依然使用’del’命令
spop随机从集合中删除一个元素,并返回
127.0.0.1:6379> sadd mset2 1 2 3 4 5 5
(integer) 5
127.0.0.1:6379> spop mset2
"4"
127.0.0.1:6379> spop mset2
"1"
127.0.0.1:6379> smembers mset2
1) "2"
2) "3"
3) "5"
本身set集合就是无秩序的集合所以删除时随机的
srandmember随机返回集合中一个元素,但不能删除
127.0.0.1:6379> srandmember mset3
"4"
127.0.0.1:6379> srandmember mset3
"3"
127.0.0.1:6379> srandmember mset3
"3"
127.0.0.1:6379> smembers mset3
1) "1"
2) "2"
3) "3"
4) "4"
5) "5"
6) "6"
scard获取集合里面的元素个数
127.0.0.1:6379> scard mset3
(integer) 6
sismember确定一个指定的值是否是集合中的元素
127.0.0.1:6379> scard mset3
(integer) 6
127.0.0.1:6379> smembers mset1
1) "3"
127.0.0.1:6379> sismember mset1 3
(integer) 1
127.0.0.1:6379> sismember mset1 2
(integer) 0
sdiff返回集合1与集合2的差集,以集合1为主
127.0.0.1:6379> sadd mset4 1 2 3
(integer) 3
127.0.0.1:6379> sadd mset5 2 3 4
(integer) 3
127.0.0.1:6379> sdiff mset4 mset5
1) "1"
127.0.0.1:6379> sdiff mset5 mset4
1) "4"
前边的集合作为标准,后面的和它进行对比
sdiffstore返回集合1和集合2的差集,并把结果存入新集合
127.0.0.1:6379> sdiff mset5 mset4
1) "4"
127.0.0.1:6379> sdiffstore mset6 mset5 mset4
(integer) 1
127.0.0.1:6379> smembers mset6
1) "4"
sinter获得两个集合的交集
127.0.0.1:6379> smembers mset4
1) "1"
2) "2"
3) "3"
127.0.0.1:6379> smembers mset5
1) "2"
2) "3"
3) "4"
127.0.0.1:6379> sinter mset4 mset5
1) "2"
2) "3"
sinterstore获得集合1和集合2的交集
127.0.0.1:6379> sinterstore mset7 mset4 mset5
(integer) 2
127.0.0.1:6379> smembers mset7
1) "2"
2) "3"
sunion获得指定集合的并集
sunionstore获得指定集合的并集,并把结果保存如新集合
127.0.0.1:6379> sunion mset4 mset5
1) "1"
2) "2"
3) "3"
4) "4"
127.0.0.1:6379> sunionstore mset8 mset4 mset5
(integer) 4
127.0.0.1:6379> smembers mset8
1) "1"
2) "2"
3) "3"
4) "4"
somve将指定的值从源集合移动到目标集合
127.0.0.1:6379> sadd mset9 1 2
(integer) 2
127.0.0.1:6379> sadd mset10 3 4
(integer) 2
127.0.0.1:6379> somve mset9 mset10 2
(error) ERR unknown command 'somve'
127.0.0.1:6379> smove mset9 mset10 2
(integer) 1
127.0.0.1:6379> smembers mset9
1) "1"
127.0.0.1:6379> smembers mset10
1) "2"
2) "3"
3) "4"
Redis数据类型
zset类型及操作
zset是set的一个升级版本,它在set的基础上增加了一个顺序属性,这一属性在添加修改元素的时候可以指定,每次指定后,zset会自动重新按新的值调整顺序。可以理解为有两列的mysql表,一列存的value,一列存的顺序。操作中key理解为zset的名字。
zadd向一个指定的有序集合中添加元素,每一个元素会对应的有一个分数。你可以指定多个分数/成员组合。如果一个指定的成员已经在对应的有序集合中了,那么其分数就会被更新成最新的,并且该成员会重新调整到正确的位置,以确保集合有序。分数的值必须是一个表示数字的字符串。
127.0.0.1:6379> zadd zset1 1 handsome 2 lingyu
(integer) 2
127.0.0.1:6379> zadd zset1 1 ingyu
(integer) 1
127.0.0.1:6379> zrange zset1 0 -1
1) "handsome"
2) "ingyu"
3) "lingyu"
zrange 返回有序集合中指定区间内的成员。其中成员按照score(分数)值从小到大排序。具有相同score值的成员按照字典顺序来排列。
127.0.0.1:6379> zrange zset1 0 -1 withscores
1) "handsome"
2) "1"
3) "ingyu"
4) "1"
5) "lingyu"
6) "2"
zrangebyscore返回有序集合中score(分数)在指定区间的值
127.0.0.1:6379> zadd zset2 1 one 2 two 3 three 4 four
(integer) 4
127.0.0.1:6379> zrange zset2 0 -1 withscores
1) "one"
2) "1"
3) "two"
4) "2"
5) "three"
6) "3"
7) "four"
8) "4"
127.0.0.1:6379> zrangebyscore zset2 2 3 withscores
1) "two"
2) "2"
3) "three"
4) "3"
zrem删除出有序集合中指定的值
127.0.0.1:6379> zrange zset1 0 -1 withscores
1) "handsome"
2) "1"
3) "ingyu"
4) "1"
5) "lingyu"
6) "2"
127.0.0.1:6379> zrem zset ingyu
(integer) 0
127.0.0.1:6379> zrem zset1 ingyu
(integer) 1
127.0.0.1:6379> zrangee zset1 0 -1 withscores
(error) ERR unknown command 'zrangee'
127.0.0.1:6379> zrange zset1 0 -1 withscores
1) "handsome"
2) "1"
3) "lingyu"
4) "2"
zincrby给有序集合中指定值的成员的分数(score)值加上增量(increment)。如果集合中没有这个值,则给添加一个分数是increment的值。
127.0.0.1:6379> zincrby zset1 2 lingyu
"4"
127.0.0.1:6379> zrange zset1 0 -1 withscores
1) "handsome"
2) "1"
3) "lingyu"
4) "4"
127.0.0.1:6379> zincrby zset1 5 lingyu
"9"
127.0.0.1:6379> zrange zset1 0 -1 withscores
1) "handsome"
2) "1"
3) "lingyu"
4) "9"
zrank返回有序集合中指定的下标。值按照score从小到大的排序
127.0.0.1:6379> zrange zset1 0 -1 withscores
1) "handsome"
2) "1"
3) "lingyu"
4) "9"
127.0.0.1:6379> zrank zset1 lingyu
(integer) 1
zrevrank返回有序集合中指定值的下标,值按照score从大到小排序。
127.0.0.1:6379> zrank zset1 lingyu
(integer) 1
127.0.0.1:6379> zrevrank zset1 liingyu
(nil)
127.0.0.1:6379> zrevrank zset1 lingyu
(integer) 0
zrank 从小到达
zrevrank是从大到小
zcount返回有序集合中,score值在起始分数与截止分数之间的个数
27.0.0.1:6379> zrange zset1 0 -1 withscores
1) "handsome"
2) "1"
3) "lingyu"
4) "9"
127.0.0.1:6379> zadd zset1 1 sc
(integer) 1
127.0.0.1:6379> zrange zset1 0 -1 withsores
(error) ERR syntax error
127.0.0.1:6379> zrange zset1 0 -1 withscres
(error) ERR syntax error
127.0.0.1:6379> zrange zset1 0 -1 withscores
1) "handsome"
2) "1"
3) "sc"
4) "1"
5) "lingyu"
6) "9"
127.0.0.1:6379> zcount zset1 1 4
(integer) 2
zcard返回有序集合元素的个数
127.0.0.1:6379> zrange zset1 0 -1 withscores
1) "handsome"
2) "1"
3) "sc"
4) "1"
5) "lingyu"
6) "9"
127.0.0.1:6379> zcard zset1
(integer) 3
zremrangebyrangk删除有序集合中,下标在指定区间的元素
127.0.0.1:6379> zremrangebyrank zset1 0 1
(integer) 2
127.0.0.1:6379> zrange zset1 0 -1 withscores
1) "lingyu"
2) "9"
zremrangebysocre删除有序集合中,分数在指定区间的元素。
127.0.0.1:6379> zrange zset1 0 -1 withscores
1) "lingyu"
2) "9"
127.0.0.1:6379> zremrangebysocre zset1 3 4
(error) ERR unknown command 'zremrangebysocre'
127.0.0.1:6379> zremrangebtscore zset1 3 4
(error) ERR unknown command 'zremrangebtscore'
127.0.0.1:6379> zremrangebyscore zset1 3 4
(integer) 0
127.0.0.1:6379>
127.0.0.1:6379> zrange zset1 0 -1 withscores
1) "lingyu"
2) "9"
zinterstore取集合1和集合2的交集,并把结果保存到新集合中。在计算交集之前,需要指定计算交集的集合的个数。交集中,值的分数是多个集合中分数的和。
127.0.0.1:6379> zadd zset3 1 one 2 two 3 three 4 four
(integer) 4
127.0.0.1:6379> zadd zset4 2 two 3 three 4 four 5 five
(integer) 4
127.0.0.1:6379> zinterstore zset5 zset3 zset4
(error) ERR value is not an integer or out of range
127.0.0.1:6379> zinterstore zset5 2 zset3 zset4
(integer) 3
127.0.0.1:6379> zrange zset5 0 -1 withscores
1) "two"
2) "4"
3) "three"
4) "6"
5) "four"
6) "8"
Redis常用命令
Redis提供了丰富的命令对数据和各种数据库类型进行操作,这些命令可以在linux终端使用。
1,键值相关命令
2,服务器相关命令
keys按照键名查找指定 的键,支持通配符。
127.0.0.1:6379> set hello 1
OK
127.0.0.1:6379> set hallo 1
OK
127.0.0.1:6379> set heeello 1
OK
127.0.0.1:6379> keys h?llo
1) "hallo"
2) "hello"
127.0.0.1:6379> keys h/llo
(empty list or set)
127.0.0.1:6379> keys h*llo
1) "hallo"
2) "heeello"
3) "hello"
exits去顶一个键是否存在 1表示键存在 0表示不存在
127.0.0.1:6379> exists name
(integer) 1
127.0.0.1:6379> exists age
(integer) 0
del删除一个键
127.0.0.1:6379> del hello
(integer) 1
127.0.0.1:6379> exists hello
(integer) 0
expire设置一个键的过期时间,如果键已经过期,将会被自动删除。
127.0.0.1:6379> set age 18
OK
127.0.0.1:6379> expire age 20
(integer) 1
127.0.0.1:6379> ttl age
(integer) 15
127.0.0.1:6379> ttl age
(integer) 13
127.0.0.1:6379> ttl age
(integer) 12
127.0.0.1:6379> exists age
(integer) 1
ttl以秒为单位,返回给定key的剩余生存时间
当key不存在时,返回-2
当key存在但没有设置剩余时间时,返回-1
否则,以秒为单位,返回key的剩存生存时间。
127.0.0.1:6379> setex mv 20 handsome
OK
127.0.0.1:6379> ttl mv
(integer) 17
127.0.0.1:6379> ttl mv
(integer) 16
127.0.0.1:6379> ttl
(error) ERR wrong number of arguments for 'ttl' command
127.0.0.1:6379> ttl mv
(integer) 13
127.0.0.1:6379> ttl name
(integer) -1
select选择一个数据库默认连接的数据库是0,可以支持共16个数据库。在配置文件中,通过databases16关键字定义。
127.0.0.1:6379> select 1
OK
127.0.0.1:6379[1]>
move将当前数据库的键移动到指定的数据空中
127.0.0.1:6379> set age 18
OK
127.0.0.1:6379> get age
"18"
127.0.0.1:6379> move age 1
(integer) 1
127.0.0.1:6379> get age
(nil)
127.0.0.1:6379> select 1
OK
127.0.0.1:6379[1]> get age
"18"
randomkey从当前数据库返回一个随机的键,如果当前数据库没有任何键,则返回nil
127.0.0.1:6379[1]> move age 0
(integer) 1
127.0.0.1:6379[1]> randomkey
(nil)
127.0.0.1:6379[1]> select 0
OK
127.0.0.1:6379> randomkey
"key3"
127.0.0.1:6379> randomkey
"key3"
rename对键值进行重命名
127.0.0.1:6379> get name
"lingyu@p163.com"
127.0.0.1:6379> rename name name_new
OK
127.0.0.1:6379> get name
(nil)
127.0.0.1:6379> get name_new
"lingyu@p163.com"
127.0.0.1:6379> get name
"lingyu@p163.com"
127.0.0.1:6379> rename name name_new
OK
127.0.0.1:6379> get name
(nil)
127.0.0.1:6379> get name_new
"lingyu@p163.com"
type返回键的类型
127.0.0.1:6379> type age
string
127.0.0.1:6379> type zset1
zset
127.0.0.1:6379> type mset5
set
127.0.0.1:6379> type list1
list
ping测试服务器是否可以链接
127.0.0.1:6379> ping
PONG
echo在命令行输出字符串
127.0.0.1:6379> echo "wo ai ni"
"wo ai ni"
quie退出redis数据库(exit或者ctrl+d都行)
save保存所有的数据。很少在生产环境直接使用SAVE 命令,因为它会阻塞所有的客户端的请求,可以使用BGSAVE 命令代替. 如果在BGSAVE命令的保存数据的子进程发生错误的时,用 SAVE命令保存最新的数据是最后的手段。
dbsize返回当前库中键的数量
127.0.0.1:6379> dbsize
(integer) 33
info获取服务器的详细信息
config get获取redis服务器配置文件中的参数。支持通配符
过了900秒并且有1个key发生了改变 就会触发save动作
过了300秒并且有10个key发生了改变 就会触发save动作
过了60秒并且至少有10000个key发生了改变 也会触发save动作
127.0.0.1:6379> config get *
1) "dbfilename"
2) "dump.rdb"
3) "requirepass"
4) ""
5) "masterauth"
6) ""
7) "unixsocket"
flushdb删除当前数据库中所有的数据
dbsize
flushdb
dbsize
Redis高级应用
安全性
主从复制
持久化
事务处理
发布及订阅消息
安全性
设置客户端连接后进行任何其他指定前需要使用密码。
警告:因为redis速度非常快—嗖,所以在一台比较好的服务器下,一个外部的用户可以在一秒内进行150K次的密码尝试,这意味着你要指定非常强大的密码来防止暴力破解。
密码三原则:复杂性、易记性、时效性
主从复制
Redis主从复制特点:
master可以拥有多个slave
多个slave可以连接同一个master外,还可以连接到其它slave
主从复制不会阻塞master,在同步数据时,master可以继续处理client请求
提高系统的伸缩性
Redis主从复制过程:
Slave与master建立连接,发送sync同步命令
Master会启动一个后台进程,将数据库快照保存到文件中,同时master主进程会开始收集新的写命令并缓存。
后台完成保存后,就将此文件发送给slave
Slave将此文件保存到硬盘上
vi /etc/sysconfig/network-scripts/ifcfg-eht0
rm -rf /etc/udev/rules.d/70-persistent-net.rule删除网卡和MAC地址绑定文件
注意关闭防火墙和SELinux
重启动系统
在slave服务器上修改配置文件
vim /usr/local/redis/etc/redis.conf
196: slaveof 192.168.66.11 6379
204: masterauth aaaaaa #没设密码可以不写
重启slave服务器的redis服务
在master的redis创建新的键,在slave端查看是否成功。
通过info命令可以查看服务器是主还是从role:master就是主role:slave就是从。
这里我们以本机配置 1台Master + 1台Slave 为例子,其中:
Master IP:127.0.0.1 PORT:6379
Slave1 IP:127.0.0.1 PORT:63791
复制出一台从服务器进行相应修改,来实现主从。
复制从服务器
cp -r /usr/local/redis/ /usr/local/redis-slave
修改从服务器配置文件
vi /usr/local/redis-slave/etc/redis.conf
pidfile /usr/local/redis-slave/redis.pid #指定pid文件
port 63791 #指定端口号
dir /usr/local/redis-slave/ #指定数据库文件存放位置
slaveof 127.0.0.1 6379 #指定主服务器IP和端口
masterauth flzx_3QC #指定主服务器密码
启动slave服务
查看两个redis端口是否都启动了
Redis是一个支持持久化的内存数据库,也就是说需要经常将内存中的数据同步到硬盘来保证持久化。
snapshotting(快照)--默认方式
append-only file(缩写aof)
snapshotting(快照)
RDB持久化方式能够在指定的时间间隔能对你的数据进行快照存储。是默认的持久化方式。这种方式是将内存中数据以快照的方式写入到二进制文件中,默认的文件名为dump.rdb。这种持久化方式被称为快照 snapshotting(快照)。
# 过了900秒并且有1个key发生了改变 就会触发save动作
# 过了300秒并且有10个key发生了改变 就会触发save动作
# 过了60秒并且至少有10000个key发生了改变 也会触发save动作
验证dump.rdb数据保存文件
cd /usr/local/redis
./bin.redis-server ./etc/redis.conf
pkill -9 redis
/usr/local/redis/bin/redis-server \
usr/local/redis/etc/redis.conf
/usr/local/redis/bin/redis-cli
由于没有添加key所以不需要手动保存
key*
save
quit
结论:在redis.conf文件中dir ./定义了数据库文件的存放位置,默认是当前目录。所以每次重启redis服务所在的位置不同,将会生成新的dump.rdb文件。
持久化使用AOF 会让你的Redis更加耐久: 你可以使用不同的持久化策略:每次写的时候备份、每秒备份、无备份。使用默认的每秒备份策略,Redis的性能依然很好(备份是由后台线程进行处理的,主线程会尽力处理客户端请求),一旦出现故障,你最多丢失1秒的数据。
append-only file(aof)
打开redis.conf配置文件开启AOF持久化
appendonly no
#默认不使用AOF持久化(450行)将no改成yes。
# appendfsync always
#有写操作,就马上写入磁盘。效率最慢,但是最安全
appendfsync everysec
#默认,每秒钟写入磁盘一次。
# appendfsync no
#不进行AOF备份,将数据交给操作系统处理。最快,最不安全
重启redis服务,登录client添加一个键值,退出然后ls命令查看下是否生成appendonly.aof。可以用cat查看。
事务处理:Redis对事务的支持还是比较简单的。Redis只能保证一个client发起的事务中的命令可以连续的执行,而中间不会插入其它的client命令。
当一个client在连接中发出multi命令时,这个链接会进入一个事务处理模式,该链接后续的命令不会立即执行,而是先储存在一个队列中,当执行对应结束命令时,redis才会对队列当中存储的命令进行依次顺序执行或取消执行。
结束事务处理输入,并且顺序执行队列当中命令
get age
multi
set age 50
set age 60
exec
get age
discard结束事务处理输入,并且清空队列当中的命令。所有已输入命令全都不执行。(类似事务回滚)
get age
multi
set age 30
set age 18
discard
get age
发布订阅(pub/sub)是一种消息通讯模式,主要的目的是解除消息发布者和消息订阅者之间的耦合,Redis作为一个pub/sub的server,在订阅者和发布者之间起到了消息路由的功能。订阅者可以通过subscribe和psubscribe命令向redis server订阅自己感兴趣的消息类型,redis将信息类型称为通道。
当发布者通过publish命令向redis server 发送特定类型的信息时,订阅该信息类型的全部client都会收到此消息。