Redis教程

来源:互联网 发布:电厂仿真软件 编辑:程序博客网 时间:2024/05/29 03:04

NoSQL 

Nosql(NoSQL=Not Only SQL),意即不仅仅是SQL,是一项全新的数据库,泛指非关系数据库

作用:

传统关系数据库在因对,超大规模和高并发SNS类型的web2.0存动态网络暴露很多难以克服的问题。

1.对数据库高并发读写的需求(高并发,双11之内的)

2.对海量数据高效存储和访问的需求(类似Facebook,twitter这样的SNS网站,每天用户产生海量的动态,就FB为例,一个月就到达2.5亿条用户动态,对于关系数据库,在一张2.5亿条记录的表里面进行sql查询,效率极其低下不可忍受)

3.对数据库高扩展性和高可用的需求(基于web的架构中,数据库是最难进行横向扩展的,当一个应用系统的用户量和访问量与日俱增的时候,你的数据库却没用办法项web server和app server 简单的通过添加更多的硬件和服务节点来扩展性能和负载能力,对于数据库的升级和扩展是非常痛苦的,往往需要停机维护和数据迁移,为什么数据库不能通过不断的添加服务器节点来实现扩展?)

NoSQL数据库就是为了解决以上难题。


主流NoSQL产品

Redis(键值对类型数据库)

MongoDB(文档类型数据库)

HBASE(列存类型据库,hadoop生态圈的数据库)


NOSQL优点

易扩展)NoSQL数据库种类繁多,有个共同点,去掉关系数据库的关系特性(数据没关联,表和表之间没联系),内存数据库,内存读写快,而且也能持久化,但是大部分都是在内存中,除非是停机断电情况下持久化,而。

高性能)NoSQL数据库高性能读写特性,尤其大数据量的时候,得利于无关系性,数据库结构简单。

灵活数据模型)NoSQL随时存储自定义数据格式,而在关系数据库,增删字段是一件非常麻烦的事情,如果是非常大数据量表,增加字段简直是一个噩梦。

高可用)NoSQL在不太影响性能的情况,就可以方便实现报可用的架构,如HBase模型,通过复制模型也能实现高可用。


什么是Redis

c语言开发开源高性能键值对(key-value)数据库,提供多种数据类型来适应不同场景下的存储需求,目前为止Redis支持类型有:

1.字符串类型

2.散列类型(相当于set)

3.列表类型(list)

4.集合类型(set)

5.有序集合类型(相当于java的TreeSet,有序集合)

以上主要指value类型

官方提供测试数据,50个并发执行100000个请求,读的速度110000次/s,写的速度是81000次/s。

Redis应用场景

缓存(数据查询,短链接,新闻内容,商品内容等),用的最多的

聊天室的在线好友列表

任务队列。(秒杀,抢购,12306等)

应用排行榜

网站访问统计

数据过期处理(可以精确到毫秒)

分布式集群架构中的session分离


Redis安装与启动

redis建议安装在linux服务器上运行测试,window版本的也可以,但是性能就不好说了。

Redis在linux上安装

1)安装redis编译的c环境,yuminstall gcc-c++

2)将redis-2.6.16.tar.gz上传到Linux系统中

3)解压到/usr/local下 tar -xvf redis-2.6.16.tar.gz -C /usr/local

4)进入redis-2.6.16目录 使用make命令编译redis

5)在redis-2.6.16目录中 使用make PREFIX=/usr/local/redis install命令安装    redis到/usr/local/redis中(这时候生成的redis/bin/redis-server可以直接访问,属于前端访问)

6)拷贝redis-2.6.16中的redis.conf到安装目录redis中,并且修改配置文件的daemonize no变为yes

7)启动redis 在bin下执行命令redis-server redis.conf(必需加上redis.conf否则还是前台启动)

关闭redis服务器两种方式

1.ps -ef|grep redis查看进程的pid然后使用kill -9 pid给关掉

2../redis-cli shutdown

8)如需远程连接redis,需配置redis端口6379在linux防火墙中开放

/sbin/iptables -I INPUT -p tcp --dport 6379 -j ACCEPT

/etc/rc.d/init.d/iptables save

Jedis对redis操作

步骤:
导入:commons-pool2-2.3.jar(连接池)
jedis-2.7.0.jar (核心)
     public void test(){//如果连接不成功,说明linux上防火墙拦截了,需要开发6379端口        Jedis jedis=new Jedis("192.168.209.134",6379);        String name = jedis.get("userName");        System.out.println(name);    }

Jedis的连接池使用

入门
    
 @Test    public void test2(){        JedisPoolConfig poolConfig=new JedisPoolConfig();        poolConfig.setMaxIdle(30);//最大闲置个数        poolConfig.setMinIdle(10);//最小现闲置个数        poolConfig.setMaxTotal(50);//最大连接数        //创建一个redis的连接池        JedisPool jedisPool=new JedisPool(poolConfig,"192.168.209.134",6379);        //从池中获取redis的连接资源        Jedis jedis = jedisPool.getResource();        jedis.set("userName","小明");        String name = jedis.get("userName");        System.out.println(name);
//关闭资源        
jedis.close();
        jedisPool.close();    
}

封装成工具类

redis.propertors

redis.maxIdle=30redis.minIdle=10redis.maxTotal=100redis.url=192.168.186.131redis.port=6379

JedisPoolUtils.javas

public class JedisPoolUtils {
private static JedisPool pool = null;static{//加载配置文件InputStream in = JedisPoolUtils.class.getClassLoader().getResourceAsStream("redis.properties");Properties pro = new Properties();try {pro.load(in);} catch (IOException e) {e.printStackTrace();}//获得池子对象JedisPoolConfig poolConfig = new JedisPoolConfig();poolConfig.setMaxIdle(Integer.parseInt(pro.get("redis.maxIdle").toString()));//最大闲置个数poolConfig.setMinIdle(Integer.parseInt(pro.get("redis.minIdle").toString()));//最小闲置个数poolConfig.setMaxTotal(Integer.parseInt(pro.get("redis.maxTotal").toString()));//最大连接数pool = new JedisPool(poolConfig,pro.getProperty("redis.url") , Integer.parseInt(pro.get("redis.port").toString()));}//获得jedis资源的方法public static Jedis getJedis(){return pool.getResource();}}

Redis常用命令

redis是一种高级的key-value的存储系统其中的key是字符串类型,尽可能满足如下几点:1)key不要太长,最好不要操作1024个字节,这不仅会消耗内存还会降低查找       效率2)key不要太短,如果太短会降低key的可读性3)在项目中,key最好有一个统一的命名规范(根据企业的需求)其中value  支持五种数据类型:1)字符串型 string2)字符串列表 lists3)字符串集合 sets4)有序字符串集合 sorted sets5)哈希类型 hashs

字符串类型string

get key 获取值set key value 设置值getset key value 先获取值后修改值del key 删除值nil 表示不存的元素incr key  递增,如果key的value是数值就加一,不是数值就报错(ERR value is not an integer or out of range),如果key不存在,则创建key,并且value初始为0+1decr key  递减,同上面一样incrby key increment  (相当于java的i+=5),如果key不存在,器初始化值为0,然后+=increment,如果该值不是数值,则报错。decrby key decrement   累减,同上特性一样append key 字符串链接,返回的是字符串长度(如果不存在,则创建字符串)

存储类型hash

每个Hash可以存储4294967295个键值对hgetkey fieldKey           获取一个Hash类型中的一个fieldKey的valuehget key fieldKey key fieldKey 可以获取多个值 hset key fieldKey value  设置一个Hash类型,并且存入fieldKey和value,返回插入结果行数hset key fieldKey value fieldKey value 可以设置多个值hdel key fieldKey    删除多个keyhdel key fieldKey fieldKey 可以删除多个值hdel key 同下del key 删除整个大的keyhmset key  fieldKey value fieldKey value.....设置一个Hash类型,并且可以存入多个fieldKey 和value,返回插入结果行数(如果存在fieldKey,返回0)hmget 类型名 fieldKey ,key.........   获取一个Hash类型,并且可以获取多个fieldKey 的value,返回LIst<String>类型。del  类型名  删除整个hashhincrby key fieldKey  value  和基本类型一样,+=一个意思,如果想-=写负数hexists  key fieldKey  判断某个key中的fieldKey是否存在,存在返回1,否则0(Jedis中是返回boolean类型)hlen key 获取key的长度hgetall key  获取全部的keyhkeys key   获取key下的所有fieldKey的名称hvals  key  获取key下的所有fieldKey的值

存储类型List

List类型是链表类型,一般可以使用到消息队列和连接池中      lpush key value value .... 左边的方式压入值rpush key value value .... 右边的方式插入值lrange key X到Y之间 (全部1 -1,-1代表最后一个元素)lpop key 弹出并且返回第一个元素,并且list中没有这个元素rpop key 弹出并且返回尾部元素,并且list中没有这个元素 lrem key count value 从左开始删除匹配到的value,删除个数为count(count参数为负数时是从左开始删除)lset  key index value  设置链表中index的脚标的元素值,如果当前的元素存在则替换,0代表链表的头元素,-1代表链表的尾元素,如果无效的下标,则异常()llen key  返回指定key关联的链表中的元素数量linsert key 之前(之后) 元素1,元素2 将元素2插入第一个元素1之前(之后)lpushx key value 仅当key存在时,向头部插入value,不存在将不进行插入rpushx key value同上,只不过是尾部插入linsert key after |before  pivot value 在pivot元素后或者前插入value这个元素rpoplpush  将链表中的尾部元素弹出并添加到头部(循环操作)

存储类型Set类型

set的元素不可重复,和List相比,set类型在功能上还存在一个非常重要的特性,即在服务器端完成多个Sets之间的聚合计算,如unions(并集),intersections(交际)和differences(差级)。由于这些操作均在服务端完成,因此效率极高,而且也节省了大量的网络io开销sadd key value,value.... 添加集合元素srem key value 删除set指定的value元素smember key  返回集合的所有元素(整个set)sdiff key key2... 返回多个集合的差级(返回不相同的)sinter key key2...  返回多个集合的交级(返回相同的)sunion key key2... 返回多个集合的并级(融合,重复的集合会被覆盖)sdiffstore destination key1 key2... 将key1和key2差集的成员存储在destination上sinterstore destination key1 key2... 将key1和key2交集的成员存储在destination上 sunionstore destination key1 key2... 将key1和key2并集的成员存储在destination上 scard key  获取set集合的数量srandmember key 返回一个随机的元素

存储类型sortedSet类型

SortedSet和Set类型极为相似,它们都是字符串的集合,并且不可重复,差别在于SortedSet中每个成员都会有一个分数(score)与之关联,正是通过分数来为集合中的成员进行从小到大的排序。尽管SortedSet成员是唯一的,但是分数(score)却可以重复。zadd key score value score value....  添加多个带有排序功能的valuezscore key value 查看元素对应的score(分数)zcard key    返回key的个数zrem key value 删除key中的valuezrang key start stop[withscores]   返回范围start 到stop之间的value,带参数显示分数zrevrange key start stop[withscores]   返回范围start到stop之间所有元素,从大到小zrangebyscore 类型名 范围0 100 0到100之间的元素withscores参数 (带分数)  limit参数(只显示多少个)zremrangebyrank key start stop 按照排名范围删除元素(默认从小到大删除)zremrangebyscore key min max 按照分数范围删除元素zrangebyscore key min max[withscores][limit offset count] 可以分页查询zincrby key  分数 value  设置value的分数zcount key min max 获取分数在min到max之间的成员zrank key member 返回成员在集合中的排名(从小到大)

Keys通用的操作

keys *  查询匹配的key(my? 查询所有开头开my的元素)

del key key.... 删除指定的多个指定的key

exists key 判断该key是否存在,1代表存在,0代表不存在

rename key newkey  重命名

expire key 设置过期时间(单位:秒)

ttl key 获取该key所剩的超时时间,如果没有设置超时时间返回-1,如果返回-2表示超时不存在type key  查询key的类型

Redis特性

多数据库,默认为0号数据库,使用客户端软件Redis Desktop Manager

命令

select 1 连接1号数据库(默认是在0库)

move newkey 1 将当前库的key剪切到1号库中

flushdb 删除当前选择数据库中的所有key

flushall 删除所有数据库中所有key

Redis的消息订阅与发布

subscribe channel 订阅频道,例:subscribe mychat,订阅mychat频道

psubscribe channel* 批量订阅频道,例:psubscribe s* ,订阅以s开头的频道

publish channel content 在指定的频道中发布消息,如 publish mychat 'today is a newday'

例:

    @Test    public void test4(){        Jedis jedis=new Jedis("192.168.209.134",6379);        jedis.publish("cctv","hello world");//发布后,上面图片接受到了    }

缺点:

所有pub/sub很有用,但是redis的实现有这么几个问题:

1.如果一个客户订阅了频道,但自己读取消息速度却不够快,那么不断积压的消息会使redis输出缓冲区的体积变得越来越大,可能使得redis的速度变慢,甚至直接崩溃。

2.这和数据传输可靠性有关,如果在订阅方断线,那么他将会丢失所有在断线期间发布者发布的消息。


Redis事务

multi 开启事务用于标记事务开始,其后执行的命令都将被存入命令队列,直到执行exec时,这些命令才会被原子的执行,

exec 提交事务

discard 事务回滚



Redis的持久化(重要)

reids的高性能是由于将所有数据存储在内存中,为了使redis在重启之后仍能保证数据不丢失,需要将数据从内存中同步到硬盘中,这一过程就是持久化
reids支持两种方式的持久化,一种是RDB方式,一种是AOF方式,可以单独使用其中一种或者二者结合使用。

1.RDB方式(默认支持,无需配置)

该机制是指在指定的时间间隔内将内存中的数据集快照以二进制的方式写入磁盘。

默认是在bin目录里面生成dump.rdb文件
2.AOF方式

该机制将以日志的形式记录服务器所处理的每一个写操作,在Redis服务器启动之初会读取该文件来重新构建数据库,以保证启动后数据库中的数据是完整的。

(以文本的方式,将所有对数据库进行过写入的命令,记录到AOF文件中,以此达到记录数据库状态的目的)
牺牲一些性能,换取更高的缓存一致性(aof)

RDB

优势

1.一旦采用该方式,那么你的整个reids数据库将只包含一个文件,这对于文件备份而言是非常完美的。比如,你可能打算每个小时归档一次最近24小时的数据,同时还要每天归档一次最近30天的数据。通过这样的备份策略,一旦系统出现灾难性故障,我们可以非常容易进行恢复。

2.对于灾难恢复而言,RDB是非常不错的选择,因为我们可以非常轻松的将一个单独的文件压缩后再转移到其它存储介质上。

3.性能最大化。对Redis的服务进程而言,在开始持久化时,它唯一需要做的只是fork(分叉)出子进程,之后再由子进程完成这些持久化工作,这样就可以极大的避免服务进程执行io操作。

4.相比于AOF机制,如果数据集很大,RDB的启动效率会更高。

  劣势

1.如果你想保证塑聚的高可用性,即最大限度避免数据丢失,那么RDB将不是一个很好的选择。因为系统一旦在定时持久化之前出现问题,此前没有来得及写入磁盘的数据都将丢失。

2.由于RDB是通过fork子进程来协助完成数据持久化工作,因此,如果当数据集较大时,可能会导致整个服务器停止服务器停止几百毫秒,甚至1秒钟。

配置说明Snapshotting

快照参数设置

save 900 1 每900秒(15分钟)至少有1个key发生变化,则dump内存快照。

save 300 10300秒(5分钟)至少有10个key发生变化,则dump内存快照。

save 60 10000 每60秒(1分钟)至少有10000个key发生变化,则dump内存快照。

使用vi打开redis.config 在命令模式下输入/save  找到以下位置(如果改目录地址可以找dir属性(默认是bin目录),改名字找dbfileame)


AOF

优势
1.该机制可以带来更高的数据安全性,即数据持久性,Redis中提供了3种同步策略,每秒同步,每修改同步和不同步,事实上,每秒同步也是异步完成的,其效率也是非常高的,所差的是一旦系统出现死机现象,那么这一秒之内修改的数据将会丢失。而每修改同步,我们可以视为同步持久化,即每次发生数据变化都会被立即记录磁盘中,可以预见,这种方式效率是最低的,至于无同步····
2.由于该机制对日志文件的写入操作采用append模式,因此写入过程出现死机也不会破坏日志文件已经存在的内容。然而如果我们只是写入了一半数据就出现了系统崩溃问题,不用担心,在Redis下次启动之前,我们可以通过redis-check-aof工具来帮助我们解决数据一致性的问题。
3.如果日志过大,Redis可以自启动用rewrite机制,即Redis以append模式不断的将修改数据写入到老的磁盘文件中,同时Redis还会创建一个新文件用于记录此期间有那些修改命令被执行。
4.aof包含一个格式清晰,易于理解的日志文件用于记录所有修改操作。
劣势
1.对于相同数量的数据,aof文件通常大于RDB文件
2.根据同步策略不同,aof在运行效率上往往会慢于RDB,每秒同步策略的效率是比较高的。

配置说明
always 每次有数据修改发生时都会写入aof文件
everysec 每秒钟同步一次(默认)
no 从不同步,高效,但是不会被持久化
个人理解:
RDB在规定时间持久化默认速度块数据不太安全
AOF在每秒(每修改)持久化 不默认 相对速度慢数据相对安全

Redis主从复制

持久化保证了Redis服务重启也不会丢失数据,因为redis服务重启后会将硬盘上的持久化数据恢复到内存中,但是当redis服务器的硬盘损坏了可能会导致数据丢失,如果通过redis的主从复制机制就可以避免这种单点故障。
说明:
主redis中数据有两个副本,即redis1和redis2,即使一台redis机器宕机其他两台可以继续提供服务
主redis中的数据和从redis上的火速局保持实时同步,当主redis写入数据时通过主从复制机制会复制到两个从redis服务上。
只有一个主redis,可以有多个从redis。
主从复制不会阻塞master,在同步数据时,master可以继续处理client请求
主的也可以当从的使用

Redis主从配置

主机配置
无需配置
从机配置
修改redis.conf的配置中的找到slaveof  ip地址 端口 

模拟主从复制

第一步:把当前的redis下的bin目录复制一个当从机用
cp bin/ bin2 -r
第二步:配置文件redis.conf文件,修改端口号
port地址为6380
第三步:配置文件redis.conf文件,更改slaveof  链接主服务器地址 端口为6379
第四步:rf -rf 清楚持久化文件
第五步:启动从机
第六步:进入6380的从机客户端
时候两个redis已经启动成功了
主机中设置一个key111
机中可以获取key111的值(从机只能读,没有写的权限


原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 mac点关机没反应怎么办 被压倒扁的易拉罐怎么办 白色车漏底漆了怎么办 客厅对着卧室门怎么办 老公不上进还懒怎么办 二胡按弦手指分不开怎么办 酷塑做完后疼痛怎么办 冷冻治疗后水泡破了怎么办 冷冻治疗的水泡破了怎么办? 冷冻治疗水泡破了怎么办 脚上冷冻后起泡怎么办 刺猴冷冻后起泡怎么办 隔壁太吵怎么办阴招 楼上有小孩太吵怎么办 捷达小水管睹了怎么办 楼房下水管冻了怎么办 一楼地面很潮湿怎么办 新房子地面有裂缝怎么办 地砖下面的下水管漏水怎么办 速冻饺子冻在一起了怎么办 牛排泡水解冻了怎么办 饺子都粘一起了怎么办 把桃子放冷冻了怎么办 抖音小视频连不上网怎么办 网络视频连不上网怎么办 苹果8视频不清晰怎么办 乳疮腐烂还臭怎么办 冰箱肉腐烂很臭怎么办 指环扣松了怎么办视频 奇迹mu端游杀人了怎么办 奇迹最强者号找不着了怎么办 v领地退不了押金怎么办 全民奇迹sf钻石变负数怎么办 电脑上的新建没有了怎么办 火车上行李箱砸人怎么办 违建拆除后怎么办房产证 外地车遇到限号怎么办 双号限行 违了怎么办 下高速当地限行怎么办 下高速发现限号怎么办 下高速正好限号怎么办