NoSQL
NoSQL(Not Only Sql),不仅仅是SQL。非关系型数据库。
随着互联网的告诉发展,传统的关系型数据库在应付超大规模的数据,超大流量以及高并发时显得力不从心。
高并发:如秒杀系统,好多人同时访问数据库就是高并发。
高负载:如facebook,twitter这样的sns网站,每天用户产生海量的用户动态,一个月就达到了2.5亿条用户动态,随着上网的人越来越多,数据也越来越多。
高可扩展性:在web的架构中,数据库是最难进行横向扩展的,当一个应用系统的用户量和访问量与日俱增时,你的数据库却没办法像增加硬件那样来扩展性能和负载能力。
NoSQL 数据库的产生就是为了剞劂大规模数据集合多重数据种类带来的挑战,尤其是大数据应用难题。
主流的NoSQL产品
Redis
mongoDB
memchche
NoSQL数据库四大分类如下:
1.键值(key-value)存储数据库 如 Redis
2.列存储数据库 如HBase
3.文档型数据库 如mongoDB
4.图形数据库
NoSQL特点
在大数据存取上具备关系型数据库无法比拟的性能优势,如:
1.易扩展
NoSQL种类繁多,但是一个共同特点就是去掉关系数据库的关系型特性。数据之间无关系,这样就非常容易扩展。
2.大数据量,高性能
NoSQL数据库都具有非常高的读写性能,尤其在大数据量下,同样表现优秀,这得益于它的无关系型,数据库的结构简单。
3.灵活的数据模型
NoSQL 无需事先为要存储的数据建立字段,随时可以存储自定义的数据格式,而在关系数据库里,增删字段是一件非常麻烦的事情。如果是非常大数据量的表,增加字段简直是一个噩梦。
4.高可用
NoSQL在不太影响性能的情况,就可以方便的实现高可用的架构。比如HBase 模型,通过复制模型也能实现高可用。
Redis
Redis是用C语言开发的一个开源的高性能键值对的数据库。他通过提供多种键值数据类型来适应不同场景下的存储需求,目前为止Redis支持的数据类型如下:
字符串类型、散列类型、列表类型、集合类型、有序集合类型。
Redis的应用场景
缓存(数据查询、短连接、新闻内容、商品内容等等)、任务队列(秒杀、抢购、12306等等)、排行榜、网站访问统计、数据过期处理、分布式集群架构中的session分离。
安装Redis
1.首先去官网下载 http://redis.io/download http://download.redis.io/releases/redis-4.0.9.tar.gz
2.安装gcc环境 yum install gcc 验证是否安装 rpm -qa | grep gcc
3.上传到linux 并解压到/usr/local下 tar -xvf redis-4.0.9.tar.gz -C /usr/local
4.进入redis文件夹 使用make命令编译
cd redis-4.0.9/
make
5.编译成功后 进入src文件夹 执行 make install
cd src
make install
6.运行src/redis-server启动Redis 服务
前端启动:src/redis-server
后端启动(需要修改daemonize为yes):src/redis-server redis.conf
配置开机自动启动
1.进入安装目录 修改配置文件 将daemonize 改为yes 后台运行
cd /usr/local/redis-4.0.9/
vim redis.conf
2.添加开机启动服务
vim /etc/systemd/system/redis-server.service
[Unit] Description=The redis-server Process Manager After=syslog.target network.target [Service] Type=simple PIDFile=/var/run/redis_6379.pid ExecStart=/usr/local/redis-4.0.9/src/redis-server /usr/local/redis-4.0.9/redis.conf ExecReload=/bin/kill -USR2 $MAINPID ExecStop=/usr/local/redis-4.0.9/src/redis-cli -h 127.0.0.1 -p 6379 shutdown [Install] WantedBy=multi-user.target
3.设置开机启动
systemctl daemon-reload
systemctl start redis-server.service
systemctl enable redis-server.service
4.查看是否启动成功
systemctl list-unit-files | grep redis
连接redis使用cli工具
/usr/local/redis-4.0.9/src/redis-cli
测试
set username zhangsan
get username
Java中操作redis
1.下载插件 jedis 、commons-pool 下载地址:https://pan.baidu.com/s/1dEMfbW1#list/path=%2F
Jedis jedis = new Jedis("10.211.55.5",6379); String username = jedis.set("username","zhagnsan"); System.out.println(jedis.get("username"));
Exception in thread "main" redis.clients.jedis.exceptions.JedisConnectionException: java.net.ConnectException: Connection refused (
2.linux 防火墙开放6379端口
查看已开放的端口号:firewall-cmd --list-ports
开启6379端口 语法:firewall-cmd --zone=public(作用域) --add-port=6379/tcp(端口和访问类型) --permanent(永久生效)
firewall-cmd --zone=public --add-port=6379/tcp --permanent
重启防火墙:firewall-cmd --reload
3.如果仍不能解决,检查redis.conf 是否bind 127.0.0.1 没注释 注释掉 protected-mode no 保护模式改为no 重启redis
redis-cli -h 127.0.0.1 -p 6379 shutdown
4.通过jedis的poll获得jedis链接对象
JedisPoolConfig config = new JedisPoolConfig(); config.setMaxIdle(30); //最大闲置个数 config.setMinIdle(10); //最小闲置个数 config.setMaxTotal(50); //最大连接数 JedisPool pool = new JedisPool(config,"10.211.55.5",6379); Jedis jedis1 = pool.getResource(); jedis1.set("sss","bbb"); jedis1.close(); pool.close();
5.redis数据类型
5.1字符串(String)
在redis中字符串类型的value最多可以容纳512M,存入类型和取出相同。
set key value //设置key的值 ,如果存在则覆盖
get key //取值 如果value不是Stirng类型,返回错误信息,如果不存在,返回null。
getset key value //先取值再设置key的值
del key //删除指定key
incr key //将value的值+1,如++,如果不存在则初始值为0,如果value不能转成整型,如hello则失败,返回错误信息。例:incr num 相当于num++
decr key //将value-1,如--,如果不存在则初始值为0,如果value不能转成整型,如hello,则失败返回错误信息。例:decr num 相当于num--
incrby key increment //将value增加increment,如果不存在,初始值0,如果value不能转成整型,如hello,则失败返回错误信息。例:incrby num 8 相当于num+=8
decrby key decrement //将value减去increment,如果不存在,初始值0,如果value不能转成整型,如hello,则失败返回错误信息。例:decrby num 5 相当于 num-=5
append key value //如果key存在,则在原有的value后追加该数值;如果该key不存在,则重新创建一个key/value 例:append num xxx 输出4xxx 拼接字符串
5.2哈希(hash)
用于存储map 键值对,每一个hash可以存储4294967295个键值对。
hset key field value //为制定的key设定 field/value对 (键值对) 如:hset myhash name tom
hget key field //返回指定的key中的field的值 如:hget myhash name
hgetall key //获取key中的所有filed-value 如:hgetall myhash
hmset key fields //设置key中的多个filed/value 如:hmset myhash name david age 27 sex man
hmget key fileds //获取key中的多个filed的值 如:hmget myhash name age sex
hexists key field //判断指定的key中field是否存在 如:hexists myhash name
hlen key //获取key所包含的field的数量
hkeys key //获取所有key
hvals key //获取所有的value
hincrby key field increment //设置key中的filed的值增加increment,如age增加20
hdel key field //删除key中的filed
del key //删除整个hash
5.3字符串列表(list)
在Redis中,List类型是按照插入顺序排序的字符串链表。可以在首尾增加新的元素。 如果插入删除中间是非常低效的。
lpush key value1 value2 ... //在指定的key所关联的list的头部插入所有的values,如果key不存在,该命令会在插入之前创建一个与该key关联的空链表,之后再向链表的头部插入数据,插入成功,返回元素个数。
rpush key value1 value2 ...//在该list的尾部添加元素
lrange key start end //获取链表从start到end的元素的值,start、end从0开始技术,可以为负数,-1表示尾部,-2倒数第二个
lpop key //返回并弹出指定的key关联的链表中的第一个元素,即头部元素。 弹出去第一个并返回列表
rpop key //从尾部弹出元素,返回剩下的列表
llen key //返回key关联的链表中的元素的数量
lpushx key value //只有key存在时,在指定的key所关联的list的头部插入value,如果不存在不会插入。
rpushx key value //在该key的list尾部添加元素。
lrem key count value //删除count个value的元素,如果count 大于0,从头向尾遍历并删除count个值为value的元素,如果count小于0,则从尾向头遍历删除,如果count等于0则删除链表中所有等于value的元素
lset key index value //在index的位置插入值并替换,0代表头,-1代表尾,索引不存在则抛异常
linsert key before|after pivot value //在pivot元素前或后插入value //linsert list before sdf zxcz sdf前插入zxcz
rpoplpush resource destlnation //将resource list中的尾部元素弹出 并添加到destlnation list头部
5.4字符串集合(set)
Set是无序的,Set集合中不允许出现重复的元素。和list相比,set可以实现多个set之间的聚合计算。
sadd key value1 value2 ... //像set中添加数据,如果该key的值已有则不会重复添加
smembers key //获取set中所有的成员
scard key //获取set中成员的数量
sismember key member //判断参数中制定的成员是否在该set中,1存在,0不存在
srem key member1 member2 //删除set中指定的成员
srandmember key //随机返回set中的一个成员
sdiff key1 key2 //返回key1与key2中相差的成员,而且与key的顺序有关。返回差集。 //sdiff one two
sdiffstore destination key1 key2 //将key1 key2相差的成员存储在destination上 //sdiffstore three one two
sinter key[key1,key2] //返回交集 //sinter one two
sinterstore destination key1 key2 //将返回的交集存储在destination上
sunion key1 key2 //返回并集 //sunion one two
sunionstore destination key1 key2//将返回的并集存储在destination上
5.5有序字符串集合(sorted set)
和sets类型非常相似,都是字符串集合,都不允许重复的成员在一个set中,sorted set中每一个成员都会有一个分数score,通过score对其进行从小到大的排序,尽管成员是必须唯一的,但score却是可以重复的。
zadd key score member score2 member2 //将所有成员以及该成员的分数放到sorted-set中 //zadd lili 4 sdf 5 qw
zcard key //获取集合中的成员数量 //zcard lili
zcount key min max //获取分数在min ,max 之间的成员 //zcount lili 0 10
zincrby key increment member //设置指定成员的增加分数 //zincrby lili 9 redis
zrange key start end [withscores] //获取集合中索引为start-end的成员 [withscores]返回的成员包含其分数 //zrangebyscore lili 0 10 zrange lili 0 -1 withscores
zrangebyscore key min max [withscores] [limit offset count] //显示分数;[limit offset count] offset 表明从索引为offset的元素开始并返回count个成员 //zrangebyscore lili 0 10 withscores limit 0 3 zrangebyscore lili 0 10 withscores
zrank key member //返回成员在集合中的位置 //zrank lili mysql
zrem key member [member ...] //移除集合中的指定成员,可以指定多个成员。 //zrem lili mysql sdf
zscore key member //返回指定成员的分数 //zscore lili redis
redis的通用操作
keys pattern //获取所有与pattern匹配的key keys * keys my*
del key1 key2 //删除key
exists key //判断是否存在该key 1存在 0不存在
rename key newkey //重命名
expire key // 设置过期时间,单位秒
ttl key //获取过期时间,如果没有设置超时返回-1,如果已过时返回-2
type key //获取指定key的类型,该命令以字符串返回,返回字符串为:string、list、set、hash、zset。如果不存在返回none
Redis移库
一个Redis实例可以包括多个数据库,客户端可以指定连接某个redis实例的哪个数据库,就好比一个mysql中创建多个数据库,客户端连接时指定连接哪个数据库。
一个Redis实例最多可提供16个数据库,下标从0到15,客户端默认连接第0号数据库,也可以通过select选择连接哪个数据库。
Redis客户端可视化工具
redis desktop manager
官网:https://redisdesktop.com/
点击connect to Redis Server 输入host 端口 连接成功 显示16个库
切换redis数据库 select index 输入0-15索引即可切换 select 1
将0库中的 one 移动到 1号库中 move one 1
退出连接 quit|exit
删除所有数据库中的所有key flushall
Redis的订阅和发布
subscribe channel //订阅频道 subscribe mychat 订阅mychat这个频道
psubscribe channel //批量订阅频道 例如 psubscribe s* 订阅以s开头的频道
publish channel content //在指定的频道中发布消息,如publish mychat 'today is a newday'
Redis的事务
multi:开启事务用于标记事务的开始,气候执行的命令都将被存入命令队列,直到执行exec时,这些命令会被原子的执行,类似begin transaction
exec : 提交事务 类似commit
discard : 事务回滚 类似 rollback
Redis的持久化
redis的高性能是由于其存储在内存中,为了使redis在重启之后仍能保证数据不会丢失,需要将数据从内存中同步到硬盘中,这一过程就是持久化。
redis支持两种方式的持久化:一种是RDB方式,一种是AOF方式。
1.RDB持久化(默认支持,无需配置)
该机制是指在指定的时间间隔内将内存中的数据集快照写入磁盘。
2.AOF持久化
该机制将以日志的形式记录服务器所处理的每一个写操作,在redis服务器重启之初会读取该文件来重新构建数据库,以保证启动后数据库中的数据是完整的。
3.无持久化
我们可以通过配置的方式禁用redis服务器的持久化功能,这样我们可以将redis视为一个功能加强版的memcached了
4.redis可以同时使用RDB和AOF
RDB
1.优势
一旦采用该方式,那么你的整个redis数据库将只包含一个文件,这对于文件备份而言是非常完美的,比如你可能打算每个小时归档一次24小时的数据,同时还要每天归档一次最近30天的数据,通过这样的备份策略,一旦系统出现故障,我们可以非常容易的进行恢复。
对于灾难恢复而言,RDB是非常不错的选择,因为我们可以非常轻松的将一个单独的文件压缩后再转移到其他存储介质上。
性能最大化。对于redis的服务进程而言,在开始持久化时,它唯一需要做的只是forx出子进程,之后再由子进程完成这些持久化的操作。这样就可以极大的避免服务进程执行IO操作了。
相比于AOF机制,如果数据集很大,RDB的启动效率会更高。
-无需配置,当数据特别多的时候适合用RDB,
2.劣势
如果你想保证数据的高可用性,即最大限度的避免数据丢失,那么RDB将不是一个很好的选择。因为系统一旦出现故障,此时还没来得急进行存储的数据都将丢失
由于RDB是通过fork子进程来协助完成数据持久化工作的,因此,如果当数据集较大时,可能会导致整个服务器停止服务几百毫秒,甚至是1秒
配置 redis.conf
save 900 1 #代表900秒 修改key1次
save 300 10 #15分钟 重新存 1次 10个以上
save 60 10000 #修改一万个key 1分钟
dbfilename dump.rdb #存储数据库的名字
dir ./ #存储位置 当前文件夹
AOF
默认没有开启
配置信息
appendonly no #如果需要 就改为yes
appendfilename "appendonly.aof" #文件名
appendfsync always #值有三个 always 每次有数据变化就会写入aof文件 everysec 每秒钟同步一次 no 从不同步,高效但是数据不会持久化
重启redis
ps -ef | grep redis
kill -9 1670
src/redis-server redis.conf
数据恢复
flushall操作 清空数据库
及时关闭redis服务器 防止dump.rdb shutdown nosave
编辑aof文件,将日志中的flushall 命令删除并重启服务即可