课程内容来自慕课网学习:
一、NoSQL介绍
(1)什么是NoSQL?
答:NoSQL=Not Only SQL ;非关系型数据库
(2)为什么需要NoSQL?
Web1.0指的是静态网页,但是无法实时动态的交互;随着动态交互的需要,才引入web2.0(动态性);
高并发读写;
海量数据的高效率存储和访问 ;
高可扩展和高可用性;
数据库最难横向扩展,当应用用户量、访问量与日剧增时,数据库没有办法像web服务器或者,应用服务器那样通过添加更多硬件来搭建我们的负载均衡的服务器,对于很多提供24小时不间断服务的系统来说,对于数据库系统升级和扩展是很痛苦的,往往需要停机维护和数据迁移。
(3)四种分类比较
(4)特点
二:redis介绍
C语言开发的开源的高性能的键值对的数据库,通过提供多种键值数据类型来适应不同场景下的存储需求,目前支持的键值数据类型有很多种
redis 是高性能键值对数据库,支持的键值数据类型:
1.字符串类型 2.散列类型 3. 列表类型 4.集合类型 5 有序集合类型
应用场景:
缓存—数据的查询,新闻和商品的查询等,聊天室的在线好友列表
任务对列
应用排行榜
网站访问统计
数据过期处理
分布式集群架构中的session分离
三、redis安装于使用
搭建环境:建议安装在linux系统中
安装过程:
下载地址官网 https://redis.io/download
安装准备:(1)VMware Workation虚拟机(2)Linux(CentOS)系统(3)SecureCRT(Xshell也行)
安装过程:
(1)安装编译器:yum install gcc-c++(需要先安装C++编译器,redis 使用c++写的)
(2)下载Redis源码并上传到服务器
(3)解压Redis压缩包:tar -zxvf *redis*
(4)进入Redis目录进行编译:make
(2/3/4步)或者直接在Linux上($符不用输入)
$ wget http://download.redis.io/releases/redis-3.2.9.tar.gz(下载)
$ tar xzf redis-3.2.9.tar.gz(解压)
$ cd redis-3.2.9
$ make(编译)
编译后是二进制文件仅在目录中 src 可用。运行Redis:
要想更好的使用还需
(5)安装Redis:make PREFIX=/user/local/redis install
(6)将redis.conf拷贝到Redis安装目录:cp redis.conf /user/local/redis
(7)进入安装目录,更改redis.conf文件:vim redis.conf --> daemonize no 改为 yes(之后可以后台模式运行)(vi 下按i 进行编辑 按esc后shift+zz(或者直接l俩大写Z),或者:wq 保存并退出)
(8)启动redis后端模式:./bin/redis-server ./redis.conf
(9)终止redis的操作 : ./bin/redis-cli shutdown
上述命令输入时遇到错误比如-bash: wget: command not found 是你电脑上没装这个功能,百度装一下就好了 这个问题 : yum -y install wget 就OK了
或者:
安装准备:(1)VMware Workation虚拟机(2)Linux(CentOS)系统(3)SecureCRT
安装过程:
(1)安装编译器:yum install gcc-c++
(2)下载Redis源码并上传到服务器
(3)解压Redis压缩包:tar -zxvf *redis*
(4)进入Redis目录进行编译:make
(5)安装Redis:make PREFIX=/user/local/redis install
(6)将redis.conf拷贝到Redis安装目录:cp redis.conf /user/local/redis
(7)进入安装目录,更改redis.conf文件:vim redis.conf --> daemonize no 改为 yes
(8)启动redis后端模式:./bin/redis-server ./redis.conf
安装在windows环境中:
关于windows系统中redis安装请见博客http://www.cnblogs.com/lojun/articles/6562164.html
简单应用:
make完后 redis-2.8.17目录下会出现编译后的redis服务程序redis-server,还有用于测试的客户端程序redis-cli,两个程序位于安装目录 src 目录下:
$ cd src
$ ./redis-server redis.conf //启动redis,后端方式
$ cd src
$ ./redis-cli //连接客户端
redis> ping
PONG
redis> set foo bar //设置foo值为bar
OK
redis> get foo //获取foo值
"bar"
redis> keys * --得到所有keys //查询所有的键
redis> del foo --删除keys //删除foo键
设置Linux的端口开放:
(1)vim /etc/sysconfig/iptables
(2)重启防火墙设置:service iptables restart
常用存储类型(字符串):0~1024个字符间
命令:
(1)存:set 键 值;取:get 键
(2)先存后取:getset 键 值
(3)删除:del 键
(4)递增:incr 键 (一定是整数;如无值则赋0后加1)
Incr num ——get num 1
Incr num ——get num 2
(5)递减:decr 键 (一定是整数;如无值则赋0后减1)
(6)增指定值:incrby 键 [integer]
(7)减指定值:decrby 键 [integer]
(8)追加(拼接)字符:append 键 "string
常用存储类型(Hash):每个可存4294967295个键值对命令
(1)存:hset 名称 键 值;多存:hmset 名称 键 值 键 值 ...
(2)取:hget 名称 键;多取:hmget 名称 键 键 ...
(3)取全:hgetall 名称
(4)删除:hdel 名称 键...
(5)全删:del 名称
(6)增指定值:hincrby 名称 键 [integer](一定是整数)
(7)判断存在:hexists 名称 键
(8)键值对数量:hlen 名称
(9)取所有键:hkeys 名称;取所有值:hvals 名称
例子:
Hset myhash username jack
Hset myhash age 18
Hmset myhash age 17 age1 10
Hget myhash username
Hmget myhash username age
Hgetall myhash
Hdel myhash name
Del myhash
Hincrby myhash age 5
Hexists myhash name1
Hlen myhash
Hkeys myhash
Hvals myhash
命令:
(1)左插入:lpush 列名 [值..];右插入:rpush 列名 [值..]
(2)查询:lrange 列名 [begin,end](两者可为正负整数,负数则从相反方向计数,正数从0开始,负数从-1开始)
(3)左弹:lpop 列名;右弹:rpop 列名(查出结果均被删除)
(4)数量:llen 列名
(5)已有列左插入:lpushx 列名 [值...];已有列右插入:rpushx 列名 [值...]
(6)移除:lrem 列名 [count] 值 (count可为正负数,负数则从相反方向计数,0为所有值)
(7)指定插入:lset 列名 [index] 值
(8)从前插入:linsert 列名 before [指定值] 值;从后插入:linsert 列名 after [指定值] 值
(9)从列右边最后元素插入指定列的左边:rpoplpush 列名 列名
命令:rpoplpush source destination
把source 中最后一个元素弹出,返回给客户端,然后把这个元素插入到destination的头部
Redis数据结构(Set):List允许出现重复数据,Set不允许出现重复数据;Set最大元素数量是4294967295
命令:
(1)存:sadd 列名 [值...]
(2)删:srem 列名 [值...]
(3)查全:smembers 列名
(4)查是否存在:sismember 列名 值
(5)差集:sdiff 列名1 列名2 (与顺序有关)
(6)交集:sinter 列名1 列名2
(7)并集:sunion 列名1 列名2
(8)查数量:scard 列名
(9)随机查:srandmember 列名
(10)将差集存到新集合中:sdiffstore 新列名 列名1 列名2
(11)将交集存到新集合中:sinterstore 新列名 列名1 列名2
(12)将并集存到新集合中:sunionstore 新列名 列名1 列名2
示例:
Sadd myset a b c
Sadd myset a //不可添加,因为已经存在a,不可以重复插入
Srem myset a b
Smembers myset
Sismember myset a
Sdiff mya1 myb1 差集
Sinter myset myset1 交集
Sunion myset myset1 并集
Scard myset 数量
Srandmember myset 随机数
Sunionstore my1 my2 my3
Redis数据结构(Sort-set):可存储有序但不重复的数据,根据分数指定存储顺序
命令:
(1)存:zadd 列名 [分数 值]...
(2)查分数:zscore 列名 值
(3)查数量:zcard 列名
(4)单删:zrem 列名 值...;范围删除:zremrangebyrank 列名 [begin,end]
zremrangebyrank key 0 4 :按照排名范围删除
zremrangebyscore key 80 100 :按照分数范围删除
(5)升序查值:zrange 列名 [begin,end] <withscores>(两者可为正负数,负数则从反方向开始计数,正数从0开始,负数从-1开始)(withscores带分数,可选项)
(6)降序查值:zrevrange 列名 [begin,end] <withscores>(两者可为正负数,负数则从反方向开始计数,正数从0开始,负数从-1开始)(withscores带分数,可选项)
(7)分数查值:zrangebyscore 列名 [begin,end] <withscores>
(8)分页查值:zrangebyscore 列名 [begin,end] <withscores limit [begin,end]>
(9)指定增加:zincrby 列名 分数 属性值;(如:zincrby mysort 3 zha,即为zha的分数+3)
(10)某个分数之间的个数:zcount 列名 [begin,end]
示例:
Zadd mysort 70 aa 80 bb 90 cc
Zadd mysort 100 aa //属性aa已经存在,此处会覆盖原来的值,即aa=100
Sorted-Set中的成员在集合中的位置是有序的.
主要的应用场景:
1.游戏的排名
2.微博的热点
3.构建索引数据
(四)Redis的Keys的通用操作
命令:
(1)所有键列:keys *
(2)指定开头键列:keys [*]? //例子:keys my?
(3)删:del 键... //可以多个,以空格分隔
(4)判断存在:exists 键
(5)重命名:rename 旧键名 新键名
(6)设过期时间:expire 键 [seconds]
(7)查过期时间:ttl 键
(8)键的值类型:type 键
(9)清空缓存:flushall
Redis特性:
(1)每个Redis实例有16个数据库,角标从0~15,默认为0
(2)开启事务会将任务放到queue中,当提交事务时逐个执行
命令:
(1)切换数据库:select [0~15]
(2)开启事务:multi
(3)提交事务:exec
(4)回滚事务:discard
select 1:选择数据库,从0开始,一个redis实例,有15个实例,这里选择1号数据库
move key1 1:把key1切换到1号数据库
Redis持久化
方式:
(1)RDB(默认):按照一定时间频率将内存中的数据或者快照保存到磁盘
(2)AOF:通过日志记录服务器操作,启动时读取日志构建数据库
(3)无持久化:配置禁用持久化,达到缓存效果
(4)RDB与AOF共用
RDB:
优点:
(1)可将数据库保存为一个文件,便于备份
(2)可方便移植
(3)性能最大化,可开启小的进程处理持久化操作
缺点:
(1)不能保证数据完整性
(2)当数据过大,进程处理将会延迟几百到一千毫秒
配置过程:
(1)编辑redis.conf文件:vim redis.conf
(2)找到时间戳,可配置秒、分、时与之存储量
(3)rdb文件默认保存在redis安装目录
AOF
优点:
(1)同步写入频率高
(2)不破坏写入日志数据
(3)当数据过大,可启动修改重写机制,保证修改数据的更新
(4)日志文件格式清晰,便于重建数据
缺点:
(1)效率低
(2)文件偏大与rdb文件
配置过程:
(1)编辑redis.conf:vim redis.conf
(2)找到 appendonly no 修改为 yes
(3)修改策略(见图)
flushall清空数据库
简单代码示例:首先引入jar包:jedis-2.8.0jar
示例一:(连接测试)
public void demo1(){ Jedis jedis=new Jedis("127.0.0.1",6379); //ip地址127.0.0.1,端口:6973 jedis.set("name", "imooc"); //设置name参数值 String values=jedis.get("name"); //获取属性name值 System.out.println(values); jedis.close(); }
连接池示例:
/** * 连接池的应用 */ @Test public void test() { // 获得连接池的配置对象 JedisPoolConfig jPoolConfig = new JedisPoolConfig(); // 设置最大连接数 jPoolConfig.setMaxTotal(10); // 设置最大空闲连接数 jPoolConfig.setMaxIdle(10); // 获得连接池 JedisPool jPool = new JedisPool(jPoolConfig, "127.0.0.1", 6379); // 获得核心对象 Jedis jedis = null; try { //通过连接池获得资源 jedis = jPool.getResource(); //设置数据 // jedis.set("name", "bob"); //获取数据 System.out.println(jedis.ping()); String value = jedis.get("num"); jedis.append("num","66"); System.out.println(value); }catch (Exception e) { e.printStackTrace(); } finally { if (jedis!=null) { //释放资源 jedis.close(); } if (jPool!=null) { //释放连接池 jPool.close(); } } }