java操作redis1
作者:互联网
1、为什么要用NOSQL
NOSQL(NoSQL = Not Only SQL),意即“不仅仅是SQL”,是一项全新的数据库理念,泛指非关系型的数据库
随着互联网的高速崛起,网站的用户群的增加,访问量的上升,传统(关系型)数据库上都开始出现了性能瓶颈,web程序不再仅仅专注在功能上,同时也在追求性能。所以NOSQL数据库应运而上,具体表现为对如下三高问题的解决:
-
High performance - 对数据库高并发读写的需求
web2.0网站要根据用户个性化信息来实时生成动态页面和提供动态信息,所以基本上无法使用动态页面静态化技术,因此数据库并发负载非常高,往往要达到每秒上万次读写请求。关系数据库应付上万次SQL查询还勉强顶得住,但是应付上万次SQL写数据请求,硬盘IO就已经无法承受了。其实对于普通的BBS网站,往往也存在对高并发写请求的需求,例如网站的实时统计在线用户状态,记录热门帖子的点击次数,投票计数等,因此这是一个相当普遍的需求。
-
Huge Storage - 对海量数据的高效率存储和访问的需求
类似Facebook,twitter,Friendfeed这样的SNS网站,每天用户产生海量的用户动态,以Friendfeed为例,一个月就达到了2.5亿条用户动态,对于关系数据库来说,在一张2.5亿条记录的表里面进行SQL查询,效率是极其低下乃至不可忍受的。再例如大型web网站的用户登录系统,例如腾讯,盛大,动辄数以亿计的帐号,关系数据库也很难应付。
-
High Scalability && High Availability- 对数据库的高可扩展性和高可用性的需求
在基于web的架构当中,数据库是最难进行横向扩展的,当一个应用系统的用户量和访问量与日俱增的时候,你的数据库却没有办法像web server和app server那样简单的通过添加更多的硬件和服务节点来扩展性能和负载能力。对于很多需要提供24小时不间断服务的网站来说,对数据库系统进行升级和扩展是非常痛苦的事情,往往需要停机维护和数据迁移,为什么数据库不能通过不断的添加服务器节点来实现扩展呢?
2、NOSQL特点
在大数据存取上具备关系型数据库无法比拟的性能优势,例如:
-
易扩展
NoSQL数据库种类繁多,但是一个共同的特点都是去掉关系数据库的关系型特性。数据之间无关系,这样就非常容易扩展。也无形之间,在架构的层面上带来了可扩展的能力。
-
大数据量,高性能
NoSQL数据库都具有非常高的读写性能,尤其在大数据量下,同样表现优秀。这得益于它的无关系性,数据库的结构简单。
-
灵活的数据模型
NoSQL无需事先为要存储的数据建立字段,随时可以存储自定义的数据格式。而在关系数据库里,增删字段是一件非常麻烦的事情。如果是非常大数据量的表,增加字段简直就是一个噩梦。这点在大数据量的Web2.0时代尤其明显。
-
高可用
NoSQL在不太影响性能的情况,就可以方便的实现高可用的架构。比如Cassandra,HBase模型,通过复制模型也能实现高可用。
3、redis特点
3.1.什么是Redis
Redis是用C语言开发的一个开源的高性能键值对(key-value)数据库,数据是保存在内存里面的. 官方提供测试数据,50个并发执行100000个请求,读的速度是110000次/s,写的速度是81000次/s ,且Redis通过提供多种键值数据类型来适应不同场景下的存储需求,目前为止Redis支持的键值数据类型如下:
- 字符串类型 string
- 散列类型 hash
- 列表类型 list
- 集合类型 set
- 有序集合类型 sortedset
3.2 redis的应用场景
- 缓存(数据查询、短连接、新闻内容、商品内容等等)
- 任务队列。(秒杀、抢购、12306等等)
- 数据过期处理(可以精确到毫秒, 短信验证码)
- 分布式集群架构中的session分离 session 服务器里面
- 聊天室的在线好友列表
- 应用排行榜
- 网站访问统计
4、Linux环境下安装
- 在虚拟机中安装c++环境
yum -y install gcc-c++
- 下载Redis
- 上传到Linux
- 解压
tar -zxf redis-4.0.14.tar.gz
- 编译
cd redis-4.0.14
make
- 安装
make install PREFIX=/usr/local/redis
- 进入安装好的redis目录,复制配置文件
cd /usr/local/redis/bin
cp /root/redis-4.0.14/redis.conf ./
- 修改配置文件
# 修改配置文件
vi redis.conf
# Redis后台启动
修改 daemonize 为 yes
# Redis服务器可以跨网络访问
修改 bind 为 0.0.0.0
# 开启aof持久化
appendonly yes
- 启动redis
./redis-server redis.conf
5、Linux命令操作
5.0、通用命令
1、基础命令
-
keys *: 查询所有的key
-
exists key:判断是否有指定的key 若有返回1,否则返回0
-
expire key 秒数:设置这个key在缓存中的存活时间
-
ttl key:展示指定key的剩余时间
若返回值为 -1:永不过期
若返回值为 -2:已过期或者不存在
-
del key:删除指定key
-
rename key 新key:重命名
-
type key:判断一个key的类型
-
ping :测试连接是否连接
2、分库命令
redis默认是16个数据库, 编号是从0~15. 【默认是0号库】
- select index:切换库
- move key index: 把key移动到几号库(index是库的编号)
- flushdb:清空当前数据库
- flushall:清空当前实例下所有的数据库
5.1、string字符串类型
1、概述
string是redis最基本的类型,用的也是最多的,一个key对应一个value。 一个键最大能存储512MB.
2、应用场景
- 缓存功能:字符串最经典的使用场景,redis最为缓存层,Mysql作为储存层,绝大部分请求数据都是在redis中操作,由于redis具有支撑高并发特性,所以缓存通常能起到加速读写和降低 后端压力的作用。
- 计数器功能:比如视频播放次数,点赞次数。
- ID递增
3、对应常见命令API
命令 | 描述 |
---|---|
SET key value | 设置指定 key 的值 |
GET key | 获取指定 key 的值 |
DEL key | 删除key |
GETSET key value | 将给定 key 的值设为 value ,并返回 key 的旧值(old value)。 |
SETEX key seconds value | 将值 value 关联到 key ,并将 key 的过期时间设为 seconds (以秒为单位)。 |
SETNX key value | 只有在 key 不存在时设置 key 的值。 |
INCR key | 将 key 中储存的数字值增一。 |
INCRBY key increment | 将 key 所储存的值加上给定的增量值(increment) 。 |
DECR key | 将 key 中储存的数字值减一。 |
DECRBY key decrement | key 所储存的值减去给定的减量值(decrement) 。 |
4、问题
假设有User对象以JSON序列化的形式存储到Redis中,User对象有id,username、password、age、name等属性,存储的过程如下: 保存、更新: User对象 ==> json(string) ==>redis
如果在业务上只是更新age属性,其他的属性并不做更新我应该怎么做呢? 如果仍然采用上边的方法在传输、处理时会造成资源浪费,下边讲的hash可以很好的解决这个问题
5.2、哈希(hash)类型
1、概述
Redis中hash 是一个键值对集合。
Redis hash是一个string类型的field和value的映射表,hash特别适合用于存储对象。
Redis存储hash可以看成是String key 和String value的map容器. 也就是说把值看成map集合.
它它特别适合存储对象相比较而言,将一个对象类型存储在Hash类型里要比存储在String类型里占用更少的内存空间并方便存取整个对象
2、应用场景
用一个对象来存储用户信息,商品信息,订单信息等等。
存储商品信息
- 商品字段【商品id、商品名称、商品价格】
- 定义商品信息的key, 商品1001的信息在 Redis中的key为:[items:1001]
- 存储商品信息
3、常见命令
命令 | 命令描述 |
---|---|
hset key filed value | 将哈希表 key 中的字段 field 的值设为 value |
hmset key field1 value1 [field2 value2]... | 同时将多个 field-value (字段-值)对设置到哈希表 key 中 |
hget key filed | 获取存储在哈希表中指定字段的值 |
hmget key filed1 filed2 | 获取多个给定字段的值 |
hdel key filed1 [filed2] | 删除一个或多个哈希表字段 |
hlen key | 获取哈希表中字段的数量 |
del key | 删除整个hash(对象) |
HGETALL key | 获取在哈希表中指定 key 的所有字段和值 |
HKEYS key | 获取所有哈希表中的字段 |
HVALS key | 获取哈希表中所有值 |
5.3、list类型
1、概述
列表类型(list)可以存储一个有序的字符串列表(链表)
,常用的操作是向列表两端添加元素,或者获得列表的某一个片段。
列表类型内部是使用双向链表(double linked list)实现的,所以向列表两端添加元素的时间复杂度为0(1),获取越接近两端的元素速度就越快。这意味着即使是一个有几千万个元素的列表,获取头部或尾部的10条记录也是极快的。
2、应用场景
如好友列表,粉丝列表,消息队列,最新消息排行等。
rpush方法就相当于将消息放入到队列中,lpop/rpop就相当于从队列中拿去消息进行消费
例子: 在Redis中创建商品评论列表,用户发布商品评论,将评论信息转成json存储到list中。用户在页面查询评论列表,从redis中取出json数据展示到页面。
3、常见命令
命令 | 命令描述 |
---|---|
lpush key value1 value2... | 将一个或多个值插入到列表头部(左边) |
rpush key value1 value2... | 在列表中添加一个或多个值(右边) |
lpop key | 左边弹出一个 相当于移除第一个 |
rpop key | 右边弹出一个 相当于移除最后一个 |
llen key | 返回指定key所对应的list中元素个数 |
LINDEX key index | 通过索引获取列表中的元素 |
LINSERT key BEFORE| AFTER pivot value | 在列表的元素前或者后插入元素 |
5.4、set集合类型
1、概述
Redis的Set是string类型的无序集合。集合成员是唯一的,这就意味着集合中不能出现重复的数据。
Redis 中 集合是通过哈希表实现的,所以添加,删除,查找的时间复杂度都是O(1)。集合中最大的成员数为 2的32次方 -1 (4294967295, 每个集合可存储40多亿个成员)。
Redis还提供了多个集合之间的交集、并集、差集的运算
特点:无序+唯一
2、应用场景
投票记录
共同好友、共同兴趣、分类标签
3、常见命令
命令 | 命令描述 |
---|---|
sadd key member1 [member2] | 向集合添加一个或多个成员 |
srem key member1 [member2] | 移除一个成员或者多个成员 |
smembers key | 返回集合中的所有成员,查看所有 |
SCARD key | 获取集合的成员数 |
SPOP key | 移除并返回集合中的一个随机元素 |
SDIFF key1 [key2] | 返回给定所有集合的差集 |
SUNION key1 [key2] | 返回所有给定集合的并集 |
SINTER key1 [key2] | 返回给定所有集合的交集 |
4、应用举例
共同好友
- A的好友
- B的好友
- A和B的共同好友
5.5、有序集合(sorted set)类型
1、概述
Redis 有序集合和集合一样也是string类型元素的集合,且不允许重复的成员。
不同的是每个元素都会关联一个double类型的分数。redis正是通过分数来为集合中的成员进行从小到大的排序。
有序集合的成员是唯一的,但分数(score)却可以重复。
集合是通过哈希表实现的,所以添加,删除,查找的复杂度都是O(1)。 集合中最大的成员数为 232 - 1 (4294967295, 每个集合可存储40多亿个成员)。
特点: 有序(根据分数排序)+唯一
2、应用场景
排行榜:例如视频网站需要对用户上传的视频做排行榜.
3、常见命令
命令 | 命令描述 |
---|---|
ZADD key score member [score member ...] | 增加元素 |
ZSCORE key member | 获取元素的分数 |
ZREM key member [member ...] | 删除元素 |
ZCARD key | 获得集合中元素的数量 |
ZRANGE key start stop[WITHSCORES] | 获得排名在某个范围的元素列表 |
4、应用举例
商品销售排行榜
- 需求:根据商品销售量对商品进行排行显示
- 思路:定义商品销售排行榜(sorted set集合),Key为items:sellsort,分数为商品销售量
- 实现
--商品编号1001的销量是9,商品编号1002的销量是10
ZADD items:sellsort 9 1001 10 1002
--商品编号1001的销量加1
ZINCRBY items:sellsort 1 1001
--商品销量前10名
ZRANGE items:sellsort -1 -9 withscores
6、java操作redis
1、简单介绍
Jedis就是使用Java操作Redis的客户端(工具包)
利用java来操作redis,官方推荐的使用工具:jedis或者是redisson
2、常用方法使用API
方法 | 解释 |
---|---|
new Jedis(host, port) | 创建jedis对象,参数host是redis服务器地址,参数port是redis服务端口 |
set(key,value) | 设置字符串类型的数据 |
get(key) | 获得字符串类型的数据 |
hset(key,field,value) | 设置哈希类型的数据 |
hget(key,field) | 获得哈希类型的数据 |
lpush(key,values) | 设置列表类型的数据 |
lpop(key) | 列表左面弹栈 |
rpop(key) | 列表右面弹栈 |
sadd(String key, String... members) | 设置set类型的数据 |
zrange(String key, long start, long end) | 获得在某个范围的元素列表 |
del(key) | 删除key |
3、使用java操作各种API
需求: 使用java代码操作Redis 进行增(改)删查
步骤:
- 导入jar
- 创建Jedis对象
- 使用方法操作
- 关闭资源
@Test
public void fun01() {
//1. 创建Jedis对象
String host = "127.0.0.1";
int port = 6379;
Jedis jedis = new Jedis(host, port);
//2. 操作Redis
//2.1 字符串
jedis.set("akey", "你好");
System.out.println(jedis.get("akey"));
jedis.del("akey");
//2.2hash
Map<String,String> map = new HashMap<String, String>();
map.put("name","zs");
map.put("sex","男");
map.put("age","18");
jedis.hmset("u1",map);
System.out.println(jedis.hget("u1", "name"));
//2.3List
jedis.rpush("l1","a","b","c","d","e","f");
List<String> l1 = jedis.lrange("l1", 0, -1);
System.out.println(l1);
//2.4Set
jedis.sadd("s1","a","b","c","d");
jedis.sadd("s2","a","b","c","d","e","f");
Set<String> set = jedis.sdiff("s2", "s1");
for (String s : set) {
System.out.println(s);
}
//3. 释放资源
jedis.close();
}
4、jedis连接池
jedis连接资源的创建与销毁是很消耗程序性能,所以jedis为我们提供了jedis的池化技术,jedisPool在创建时初始化一些连接资源存储到连接池中,使用jedis连接资源时不需要创建,而是从连接池中获取一个资源进行redis的操作,使用完毕后,不需要销毁该jedis连接资源,而是将该资源归还给连接池,供其他请求使用。
4.1、步骤
@Test
// 使用池子来获得jedis jedis当做方便面 开工厂 张三 100个工人 李四
public void fun01() {
//0 创建池子配置对象
JedisPoolConfig poolConfig = new JedisPoolConfig();
poolConfig.setMaxTotal(10);//设置最大连接数量(可以不配...)
String host = "localhost";
int port = 6379;
//1. 创建Jedis池子对象
JedisPool jedisPool = new JedisPool(poolConfig, host, port);
//2. 从池子里面获得jedis
Jedis jedis = jedisPool.getResource();
//3. 操作redis数据库
//3.1 存
//jedis.set("ckey", "ccc");
//3.2 取
//System.out.println(jedis.get("ckey"));
//3.3 删除
jedis.del("ckey");
//4. 释放
jedis.close();
jedisPool.close();
}
标签:java,redis,redis1,value,jedis,key,集合,操作,Redis 来源: https://www.cnblogs.com/likeguang/p/15910594.html