.Net转Java自学之路—Redis篇
Redis:
关系型数据库(SQL):MySQL、Oracle
特点:数据与数据之间,表与字段之间,表与表之间是存在关系的
优点:
1、数据之间有关系,进行数据的增删改查时非常方便。
2、关系型数据库,有事物操作。保证数据的完整性。
缺点:
1、因为数据和数据之间有关系,是由底层大量算法保证的。大量算法会拉低系统运行速度。大量算法会消耗系统资源
2、海量数据的增删改查时,会显的无能为力。在做某些操作时,很可能会宕机(卡死)
3、在海量数据环境下对数据表进行维护/扩展,也会变得无能为力。适合处理一般量级的数据。保证的是安全。
非关系性数据库(NOSQL):Redis、mongoDB
为了处理海量数据,需要将关系型数据库的关系 去掉。非关系型数据库设计之初,是为了替代关系型数据库的。
优点:
1、海量数据的增删改查,非常轻松。
2、海量数据的维护/扩展,也会非常轻松。
缺点:
1、因为数据与数据之间没有关系,所以不能一目了然。
2、非关系型数据库,没有关系,没有强大的事物来保证数据的完整和安全。
适合处理海量数据,保证的是效率。不一定安全。
NoSql数据库的四大分类:
1、键值(Key-Value)存储数据库。
相关产品:Tokyo Cabinet/Tyrant、Redis、Voldemort、Berkeley DB
典型应用:内容缓存,主要用于处理大量数据的高访问负载
数据模型:一系列的键值对。
优势:优秀的快速查询,稳定性强。
劣势:存储的数据缺少结构化。
2、列存储数据库
相关产品:Cassandra、HBase、Riak
典型应用:分布式的文件系统。
数据模型:以列簇式存储,将同一列数据存储在一起。
优势:查找速度快,可扩展性强,更容易进行分布式扩展
劣势:功能相对局限,使用极大的内存才可调配,且系统处理算法时将有数秒,甚至更长时间的不可用,导致大量处理超时。
3、文档型数据库(淘汰)
相关产品:CouchDB、MongoDB
典型应用:Web应用(与Key-Value类似,Value时结构化的)
数据模型:一系列键值对
优势:数据结构要求不严格
劣势:查询性能不高,而且缺乏统一的查询语法。
4、图形(Graph)数据库:
相关产品:Neo4J、InfoGrid、Infinite Graph
典型应用:社交网络(关系网)
数据模型:图结构
优势:利用图结构相关算法。
劣势:需要对整个图做计算才能得出结果,不容易做分布式的集群方案。局限性过强。
Redis使用环境:
1、可以作为关系型数据库的缓存存在。
2、可以做任务队列。
3、可以做大量数据运算。
4、可以做大量数据的排行榜。
Linux系统 Redis 安装:
redis是C语言开发,安装redis需要先将官网下载的源码进行编译,编译依赖gcc环境。如果没有gcc环境,需要安装gcc:yum install gcc-c++
1、上传redis.tar.gz的安装包。并解压到当前目录:tar -zxvf redis-3xxxxx.tar.gz
2、编译redis(编译,将.c文件编译为.o文件)
进入解压文件夹:cd redis-3xxxxx
执行 make
如果没有安装gcc,编译将出现错误提示。(安装失败,必须删除文件夹,重新解压)
3、安装:make PREFIX=/usr/local/redis install
PREFIX指定的目录可以随意指定。
安装完后,在/usr/local/redis/bin下有几个可执行文件:
redis-benchmark >> 性能测试工具
redis-check-aof >> AOF文件修复工具
redis-check-dump >> RDB文件检查工具(快照持久化文件)
redis-cli >> 命令行客户端
redis-server >> redis服务器启动命令
4、回到根目录:cd ~ 进入redis-3xx 文件中,
Copy复制redis.conf文件到/usr/local/redis目录下(和bin同级目录中)
注:若没有配置文件redis也可以启动,不过将启动默认配置,不方便修改端口号等信息。
Redis启动:对应默认端口号6379
前端启动:进入/usr/local/redis文件夹下:./bin/redis-server 启动
启动客户端:./bin/redis-cli 或 ./bin/redis-cli -h IP地址 -p 6379
缺点:无法部署集群。
后端启动:修改redis.conf配置文件,将daemonize改为yes以后端模式启动
启动时,指定配置文件:进入/usr/local/redis:cd /usr/local/redis
启动:./bin/redis-server ./redis.conf
Redis关闭:
1、查询PID,kill -9 pid 杀死进程。
相当于断电,非正常关闭,很可能会造成数据丢失。
2、正常关闭:正常关闭,数据保存
./bin/redis-cli shutdown
Redis数据类型:
redis使用的时键值对 保存数据。相当于Map 。
key:都是字符串。key名都是自定义的。
value:对应五种数据类型
1、String字符串
2、hash:数据格式类似于JSON
例:{uname:"zs",age:"18"}
3、list集合: 相当于Java中的LinkedList链表。添加/删除效率极高。
例:[1,2,3,4]
4、set:相当于Java中的HashSet
例:['a','b','c']
5、有序的set集合:
例:[1000 'a',100 'b' 10 'c']
String:
字符串类型时Redis中最为基础、常用的数据存储类型。字符串在Redis中二进制安全的。这意味者该类型存入和获取的数据相同。在Redis中字符串类型的Value最多可以容纳的数据长度为512M。
二进制安全和数据安全是没有关系的。
MySQL关系型数据库,二进制不安全。因为存储的编码和取出的编码格式不一致,会造成乱码而丢失数据。
1、频繁的编解码会浪费大量的系统性能。
2、频繁的编解码很可能因为码表不同导致乱码。
所以二进制不安全。
Redis非关系型数据库,二进制安全。
1、编解码都是在客户端完成的。没有频繁编解码,执行效率高。
2、没有频繁编解码,不会出现乱码。
所以二进制数据安全。
赋值(增、改):
set key value :设定key只有指定的字符串value
如果该key存在则进行覆盖(修改)操作。总是返回"OK"
取值(查):
get key:获取key的value。若该key的关联的value不是String类型,redis将返回错误信息,因为get命令只能用于获取String类型的value;若该key不存在,返回(nil)。
删:
del key :删除指定key。返回值是数字类型。表示删除几条数据。
扩展:
getset key value:先获取该key的值,再设置该key的值。
incr key:将指定的key的value原子性的递增1。
若该key不存在,其初始值为0,再incr之后其值为1。
若value的值不能转成整型,该操作将执行失败并返回相应的错误信息。
decr key:将指定的key的value原子性的递减1。
若该key不存在,其初始值为0,再decr之后其值为-1。
若value的值不能转成整型,该操作将执行失败并返回相应的错误信息。
append key value:拼凑字符串。
若该key存在,则在原来的value后追加该值。
若该key不存在,则重新创建一个key,并赋值value。
incrby key increment:将指定的key的value原子性增加increment。
若该key不存在,其初始值为0,在incrby后,其值为increment。
若该值不能转成整型,则失败并返回错误信息。
decrby key decrement:将指定的key的value原子性减少decrement。
若该key不存在,其初始值为0,在decrby后,其值为decrement。
若该值不能转成整型,则失败并返回错误信息。
String的使用环境:主要用于保存JSON格式的字符串。
hash:
Redis中的Hash类型可以堪称具有String key和String value的map容器。每一个Hash可以存储4294967295个键值对。
赋值:
hset key field value :为指定的key设定field/value对(键值对)。相当于 增。
hmset key field value field1 value1...:为指定的key设定多个field/value对(键值对)。
取值:
hget key field:获取指定的key的field值。
hmget key field field1...:获取指定key的多个field值。
hgetall key:获取key中的所有field-value。
删除:
hdel key field field1...:删除一个或多个field字段。
del key:删除正个hash。
扩展:
hincrby key field increment :设置key中field的值增加increment。
hexists key field :判断指定的key中filed是否存在。
hlen key :获取key所包含的field的数量。
hkeys key :获取所有的字段。
hvals key :获取所有的value。
list:
链表LinkList。Redis操作中,最多的操作是进行元素的增删。
使用环境:
1、做大数据集合的增删
2、做任务队列
赋值:
lpush key values[value1 value2...]:在指定的key所关联的list头部插入所有的values。
若该key不存在,该命令在插入的之前创建一个与该key关联的空链表,之后再向该链表的头部插入数据。插入成功,返回元素的个数。
例:lpush list1 a b c d
rpush key values[value1 value2...]:在该list的尾部添加元素。
例:rpush list2 a b c d
取值:
lrange key start end:获取链表中从start到end的元素的值。start、end从0开始计数;也可为负数。
若为-1 则表示链表尾部的元素;-2 则表示倒数第二个元素;以此类推...
例:取全部元素:lrange key 0 -1
删除:
lpop key:返回并弹出指定的key关联的链表中的第一个元素,即头部元素。
若该key不存在,返回nil;
若该key存在,则返回链表的头部元素。
rpop key:从尾部弹出元素。
扩展:
llen key:返回指定的key关联的链表中的元素的数量。
lrem key count value:删除某种元素。效率极为低下。删除count个值为value的元素。
若count大于0,从头向尾遍历并删除count个值为value的元素。
若count小于0,则从尾向头遍历并删除正数count个值为value的元素。
若count等于0,则删除链表中所有等于value的元素。
例:lrem list1 0 a 表示从左删除list1中所有的a
lrem list1 2 a 表示从头删除list1中的2个a
lrem list1 -2 a 表示从尾删除list1中的2个a
lset key index value:通过索引替换元素。效率不高。设置链表中的index的角标的元素值。0代表链表的头元素,-1代表链表的尾元素。操作链表的角标不存在则抛异常。
linsert key before/after prvot value:从索引前/后插入元素。效率不高。在pivot元素前或后插入value这个元素。
rpoplpush resource destination:将链表中的尾部元素弹出并添加到头部。[循环操作]
例:rpoplpush list1 list2 俩队排列
rpoplpush list1 list1 循环队列
set:
set集合中不允许出现重复的元素。
作用:在Redis操作中,涉及到俩个大数据集合的并集、交集、差集的运算。
赋值:
sadd key values[value1、value2...]:向set中添加数据,若该key的值已存在则不会重复添加
例:sadd set1 a b c d
取值:
smembers key :获取set中所有元素。
例:smembers set1
sismember key member:判断参数中指定的成员是否在该set中。1 表示存在,0 表示不存在或该key本身就不存在。无论集合中有多少元素都可以极快的返回结果。
例:sismember set1 a 判断集合set1中是否有a元素
删除:
srem key values[value1、value2...]:删除set中指定的元素
例:srem set1 a c
差集运算:
sdiff key1 key2...:返回key1与key2中相差的元素,而且与key的顺序有关。即返回差集。
交集运算:
sinter key1 key2 key3...:返回交集
并集运算:
sunion key1 key2 key3...:返回并集
扩展:
scard key:获取set中元素的数量。
srandmember key :随机返回set中的一个元素。
sdiffstore destination key1 key2...:将key1、key2相差的元素存储在destination上
例:sdiffstore set1 set2 set3 将set2与set3的差集元素存储到set1中。
sinterstore destination key[key...]:将返回的交集存储在destination上
例:siterstore set1 set2 set3 将set2与set3的交集元素存储到set1中。
sunionstore destination key[key...]:将返回的并集存储在destination中
例:sunionstore set1 set2 set3 将set2与set3的并集元素存储到set1中。
有序set集合:
有序且不重复。有序set集合专门用来做排行榜。
赋值:
zadd key score member score2 member2...:将所有元素以及该元素的分数存放到sorted-set中。若该元素已经存在,则会用新的分数替换原有的分数。返回值是新加入到集合中的元素个数,不包含之前已经存在的元素。
例:zadd set1 1000 zhangsan 100 lisi 10 王五
查看:
zscore key member:返回指定元素的分数。
例:zscore set1 zhangsan
zcard key : 获取集合中的元素数量
例:zcard set1
zrange key start end[withscores]:范围查询。获取集合中脚标为start-end的元素,[withscores]参数表明返回的元素包含分数。
例:zrange set1 0 -1 查询所有元素。正序排列。由小到大
zrange set1 0 -1 withscores 查询所有元素。并且带有各自的分数。正序。由小到大
zrevrange key start end[withscores]:范围查询。获取集合中脚标为start-end的元素,[withscores]参数表明返回的元素包含分数。
例:zrevrange set1 0 -1 查询所有元素。倒序排列。由大到小
zrevrange set1 0 -1 withscores 查询所有元素。并且带有各自的分数。倒序。由大到小
删除:
zrem key member[member...]:删除集合中指定元素。可以指定多个。
例:zrem set1 zhangsan lisi
zremrangebyrank key start stop:按照排名范围删除元素。
例:zremrangebyrank set1 0 1 删除前俩名
zremrangebyscore key min max:按照分数范围删除元素。
例:zremrangebyscore set1 50 500 删除分数在50到500之间的元素
扩展:
zrangebyscore key min max[withscores][limit offset count]:返回分数在min-max的元素并按照分数从低到高排序。[withscores]:显示分数;[limit offset count]:offset,表明从脚标为offset的元素开始,并返回count个元素。
例:zrangebyscore set1 50 500 返回分数在50-500之间的元素。
zrangebyscore set1 50 500 withscores 返回分数在50-500之间的元素。加上分数。
zrangebyscore set1 50 500 withscores limit 0 1 返回分数在50-500之间的元素。加上分数。并且只查前1个元素。
zincrby key increment member:设置指定成员的增加分数。返回更改后的分数
例:zincrby set1 10 zhangsan 给zhangsan增加10分。
zcount key min max: 获取分数在min-max之间的元素。
例:zcount set1 50 500 计算50-500分数之间的元素由多少
zrank key member:返回成员在集合中的排名。索引(从小到大)
例:zank set1 zhangsan 返回zhangsan的排名。
zrevrank key member:返回元素在集合中的排名。索引(从大到小)
例:zrevrank set1 zhangsan 返回zhangsan的排名。
通用命令:
keys pattern:获取所有与pattern匹配的key,返回所有与该key匹配的keys。
通配符:
*:表示任意一个或多个字符。
?:表示任意一个字符。
例:keys * 查询所有的key
keys ???? 查询key长度是四位的key名。
keys *name* 查询key名包含name的key名。
del key1 key2...:删除指定的key。可以指定多个。
exites key:判断该key是否存在,1代表存在。0代表不存在。
rename key newkey:为当前的key重命名。
type key:获取指定key的类型。该命令将以字符串的格式返回。返回的字符串为string、list、set、hash和zset。如果key不存在,则返回none。
设置key有效时间:
expire key:设置过期时间。单位:秒
ttl key:获取该key所剩的超时时间,若没有设置超时,返回-1。若返回-2,表示超时不存在。
消息订阅与发布:
subscribe channel:订阅频道。
例:subscribe mychat 订阅mychat这个频道。
psubscribe channel*:批量订阅频道。
例:psubscribe s* 订阅以s开头的频道。
publish channel content:在指定的频道中发布消息。
例:publish mychat 'abcdefg'
多数据库:
Redis的数据库已经提前创建好了,默认有16个数据库。数据库的名字是0,1,2...15号数据库。在redis上所做的所有数据操作,都是默认在0号数据上操作的。数据库与数据库之间,是不能共享键值对的。
切换数据库:select 数据库名(1,2,3...15)
把某个键值对进行数据库的移植:move key 1:将key键移植到1号数据库中。
清空当前数据库:flushdb
清空所有的数据库内容:flushall
事物:
mysql的事物是为了保证数据完整性,安全。
Redis的事物是为了进行redis语句的批量化执行。
multi:开启事物,用于标记事物的开始,其后执行的命令都将被存入命令队列,知道执行EXEC时,这些命令才会被原子的执行。
类似与关系型数据库中的:begin transaction
exec:提交事物,类似与关系型数据库中的:commit
discard:事物回滚,类似与关系型数据库中的:rollback
了解命令:
ping:返回PONG为已成功连通
echo:在命令行打印一些内容 echo hehe
select:切换数据库 select 1
quit:退出客户端。等同于:Ctrl+C
dbsize:返回当前数据库中key的数量。
info:获取服务器的信息和统计。
持久化:把数据保存在硬盘上。
关系型数据库MySQL-持久化:
任何的增删改语句,都是在硬盘上做的操作。
断电以后,硬盘上的数据还是存在。
非关系型数据库Redis-持久化:
默认情况下,所有的增删改,数据都是在内存中进行操作。
断电以后,内存中的数据不存在。redis的部分数据会丢失,丢失的数据时保存在内存中的数据。所以Redis是存在持久化操作的。
Redis有俩种持久化策略:
RDB:是Redis的默认持久化机制。RDB相当于照快照,保存的是一种状态。
优点:
1、快照保存数据速度极快,还原数据速度极快。
2、适用于灾难备份。
缺点:
1、小内存机器不适合使用。因为RDB机制符合要求就会照快照。(随时随地启动)会占用部分系统资源(突然的占用),很可能内存不足直接宕机。
适用于:内存比较充裕的计算机。
RDB何时进行照快照:
1、服务器正常关闭时,照快照。
2、key满足一定条件时,照快照。
配置说明:
1、save 900 1:每900秒至少有一个key发生变化,则dump内存快照。
2、save 300 10:每300秒至少有10个key发生变化,则dump内存快照。
3、save 60 10000:每60秒至少10000个key发生变化,则dump内存快照。
AOF:
使用日志功能保存数据的操作。适用于:内存比较小的计算机。
每秒同步(默认):每秒进行一次AOF保存数据。安全性低,但比较节省系统资源。
每修改同步:只要有key变化语句,就进行AOF保存数据。比较安全,但极为浪费系统资源。
不同步:不进行任何持久化操作。不安全。
AOF操作:
只会保存导致key变化的语句。
AOF配置:
AOF默认时关闭的。
开启AOF:
1、appendonly yes
2、放开 appendfsync always
always:每次有数据修改发生时都会写入AOF文件。
everysec:每秒同步一次,该策略为AOF的缺省策略。
no:从不同步,高效但数据不会被持久化。
优点:
持续性占用极少量的内存资源。
缺点:
1、日志文件会特别大,不适用于灾难恢复。
2、恢复效率远远低于RDB。
Jedis:
所有的Redis命令,Jedis都有对应的方法。
Java中连接Redis数据库需要开启Linux中Redis对应的端口号:
/shin/iptables -I INPUT -p tcp --dport 6379 -j ACCEPT
/etc/rc.d/init.d/iptables save
单实例连接Redis数据库:Jedis jedis=new Jedis("IP",6379);
Jedis连接池:
JedisPoolConfig config = new JedisPoolConfig();//设置连接池的配置对象 //可以不设置池的参数 config.setMaxTotal(int);//设置池中最大连接数 config.setMaxIdle(int);//设置空闲时池中包有的最大连接数 JedisPool pool = new JedisPool(config,"IP",6379);//设置连接池对象 Jedis jedis=pool.getResource();//从池中获取连接对象。 jedis.get("name"); jedis.close();//连接归还池JedisPool中
JedisUtils:
public class JedisUtils{ //定义一个连接池对象 private final static JedisPool POOL; static{//初始化操作 JedisPoolConfig config = new JedisPoolConfig(); config.setMaxTotal(int); config.setMaxIdle(int); POOL = new JedisPool(config,"IP",6379); } //从池中获取连接 public static Jedis getJedis(){ return POOL.getResource(); } }