Redis
一. Redis入门
@NoSQL概述
名字:Not Only SQL
非关系型数据库:
1. 为了适应Web2.0网站这种动态和高并发的情况
2. 对海量数据高效率存储和访问
3. 高可扩展性和高可用性
4. 数据库之间去掉关系容易扩展
关系型数据库:
1. 或许处理上万次的读的操作的时候还可以应付,但是处理上万次写的操作的时候可能就不太行了
2. 更新维护时候要添加更多的硬件达到负载均衡,要停机维护
@NoSQL四大类型
1. 键值对(优势:快速查询 劣势:缺少结构化)
2. 列存储 (优势:查找速度快,扩展性强 劣势:功能局限)
3. 文档存储 (MongoDB 优势:存储要求不高 劣势:查询性能不高)
4. 图形数据库 (优势:可以对图进行存储 劣势:要对图进行运算,不能分布式)
二. Redis概述
由来:来自意大利的一家创业公司
它的创始人觉得mysql不够好用就自己开发了Redis然后又希望让它适用于大众,然后和另外一个人继续开发它。
调查报告:Redis又近百分之十二的公司在使用(国内:新浪微博,知乎)
Redis是用C语言开发的高性能键值对的数据库,通过提供多种不同数据类型来支持不同场景需求
支持类型:
字符串类型 列表类型 散列类型 有序集合类型 集合类型
官方:读:11万次/s 写:8.1万次/s
应用场景:缓存 聊天好友列表 任务队列(秒杀网站) 网站访问统计 数据过期处理(精确到毫秒) 应用排行榜 分布式集群架构中的session分离
三. Redis安装
建议在Linux系统上面安装
由于Redis是C语言开发的,安装先到官网下载源码,编译依赖gcc环境,首先先安装gcc
(CentOS为例)
yum install gcc-c++
安装完成
虚拟机为例:先把redis的压缩包下载下来然后上传到Linux的root目录下
tar -zxvf XXXXXXXX解压
解压后进入redis那个目录直接终端输入make就OK了,前提是有C环境
安装:makePREFIX=/usr/local/redis install
Cd /usr/local
可以看到里面就有一个redis的目录了
进入这个目录有一个bin路径,进入
Redis-benchmark 性能测试的工具
Redis-check-aof aof修复工具
Redis-cli 命令行的一个客户端
Redis-server redis服务器启动的一个命令
现在回到刚才解压完的redis压缩包的目录里,看到有个文件叫redis.conf,把这个文件放到刚才那个目录下:cp redis.conf/usr/local/redis
Cd /usr/local/redis/bin
./redis-server(启动redis,前端启动,不能对它进行操作,我们一般采用后端启动方式,按Ctrl c退出)
Cd ../
Vim redis.conf修改配置文件
进入编辑模式,找到一行配置 daemonize no
把no改成yes
把文件保存
然后cd ./bin
./redis-server./redis.conf (不前端启动,要加载配置文件)
查看是否启动成功:ps -ef | grep -iredis
默认端口6379
关闭redis:进入bin路径
然后./redis-cli shutdown
把redis打开之后要开启客户端:./redis-cli
可以在命令行看见自己的主机号
输入一个ping
得到结果PONG(说明连接没有问题)
存入数据 set nameXXX (name为key,XXX为value)
查: get name
删: del name
Keys *查所有的key
四. Jedis入门
这是redis连接的一个基本操作,客户端操作
Jedis是Redis官网首选的Java开发包
可以上GitHub上面去下载下来
打开eclipse,新建一个项目叫Jedis,在项目下新建文件夹叫lib,然后把之前下载下来的那个文件夹里面的两个文件复制到lib里面,然后选中两个包右键,有一个Build Path,Build Path下面有一个Add to Build Path(把我们的包添加到路径里面),就引好了。
/src里面新建一个Package叫com.XXXXX.jedis
新建一个Java类(我的叫demo)
引入:
import org.junit.Test
importredis.clients.jedis.Jedis
定义一个方法
public void xxxx(){
//设置IP和端口
Jedis jedis =new Jedis(“IP”,6379);
//保存数据
jedis.set(“key”,”value”);
//获取数据
String value =jedis.get(“key”);
System.out.println(value);
//释放资源
Jedis.close();
}
来运行一下会出现错误,其实是因为Linux系统没有开放6379这个端口
来到Linux,修改防火墙设置: vim /etc/sysconfig/iptables
把打开22端口那行复制粘贴然后改成6379
重启防火墙
还有一种方法用连接池方式调用
public void xxxx(){
//获得连接池配置对象
JedisPoolConfig config = new JedisPoolConfig();
//设置最大连接数
config.setMaxTotal(50);
//最大空闲连接数
config.setMaxIdle(20);
//获得连接池
JedisPool jedisPool = new JedisPool (config,”IP”,6379);
//获得核心对象
Jedis jedis = null;
try{
//通过连接池获得连接
Jedis = jedisPool.getResource();
//设置数据
jedis.set(“key”,”value”)
//获取数据
String value = jedis.get(“key”);
System.out.println(value);
}catch(Exception e){
e.printStackTrace();
}finally{
//释放资源
if(jedis != null){
jedis.close();
}
//释放连接池
if(jedisPool != null){
jedisPool.close();
}
}
}
五. Redis数据结构
五种数据结构:
字符串String 哈希hash 字符串列表list 字符串集合set 有序字符串集合sorted set
Key不能超过1024字节,也不能太简单
字符串:
value最多容纳512M,二进制
incr num(如果数据库没这个值会将它设置为0然后增加1,如果有值在这个基础上加一)
incr 字符串(报错)
incrby num 5 (加5)
Hash
键值对的类型,适合存用户名密码这样的字段
每一个hash可以存储4294967295个键值对(非常多)
赋值:hset myhashusername Tom
hmset myhash2 username Tomage 21 (多个)
取值:hget myhash username
hmget myhash username age
hgetall myhash
删除:hdel myhash2username age
del myhash2 (删除整个)
增加数字:hincrby myhash age5
检查是否存在:hexists myhash username
得到长度:hlen myhash
得到所有的key:hkeys myhash
同理:hvals myhash
List
一个链表,可以在头部和尾部插入元素,如果数据在链表中间,效率就慢了
ArrayList相当于线性表,增删比较麻烦
LinkedList双向链接,相当于链表
左侧添加数据:lpush mylist a bc
右侧同理
查看:lrange mylist 05 (从0到5)
左端弹出:lpop mylist
右端同理
查长度:llen mylist
删除:lrem mylist countvalue (count大于零从左到右删除count个值为value的元素,count小于零从右向左删除count个元素,等于0删除所有)
设置:lset mylistcount value 在某个位置设置value值
插入:linsert mylistbefore b 1 在第一个b前插入1
rpoplpush mylist1mylist2 把1中的尾部压入2
Set
和list不同,set是不允许出现重复数据的
Set可包含最大元素量:4294967295
sadd myset a b c
srem myset a b
smembers myset
sismember myset a
不同:sdiff myset1myset2
交集:sinter m1 m2
还有些扩展的方法就实际用到的时候查吧
Sorted-set
和set的区别是它每一个成员是有一个分数的,然后他是按分数从小到大排序的,成员是唯一的,分数不唯一
六. Redis通用命令
keys my? my开头的几个key
del my1 my2 删除
exisits my1
rename company newcompany
get company
expire newcompany 1000 (设置过期的时间,单位是s)
ttl newcompany 查看过期时间
type myset
七. Redis事务
Select 1 选择一号数据库,默认是0
move myset 1 移到1号数据库
multi exec discard来实现我们的事务,为了保证事务串行原子化执行,不会为别的客户端提供服务
和关系型数据库相比redis在某个任务执行失败后,后面的任务还会被执行
muti 开启事务,这之后的命令都被视为是事务里面的相关操作
exec 相当于提交了
事务开启之前如果客户端和服务器之间出现通讯故障并导致网络断开,那么他之后所执行的语句将不会被执行,如果网络中断时在exec之后的那么都会被执行
例:
打开两个客户端窗口,第一个开启事务multi,然后改变变量的值,第二个窗口就看不到了,只有当第一个窗口exec,第二个窗口才能看到
Discard 代表不提交
八. Redis持久化
@保存在内存中的数据在redis停止后为了不丢失,过渡到硬盘上的操作被称为持久化
两种方式:
RDB方式
AOF方式
RDB方式:指定时间把数据写到硬盘
AOF方式:日志方式记录每一个操作,然后重新构建数据库