您的位置:首页 > 数据库 > Redis

Redis起步安装及基本命令--JAVA(系列文章一)

2017-05-12 11:22 627 查看
Redis的一些介绍我也不说的比较详细了,redis是一个内存数据库,同时也支持持久化操作,对比与memcached来说多了几种数据存储结构,所以基本上你用了redis之后你就会慢慢疏远memcached的,我就是一个典型的例子,因为redis提供的HASH和ZSET实在是非常好用了,对于一些场景来说简直是神器。而且redis的复制技术让存储集群成为了可能。这系列文章我会使用JAVA作为操作Redis,没有别的因为我写JAVA比较多。之后的文章也会结合Spring去对redis进行整合,当然这篇文章最终要也是为了将一些技术点记录下来,方面以后查阅。

我是使用Mac作为开发环境的,所以安装非常简单,只要使用brew进行安装即可。如果没有按照brew可以先安装,官网:https://brew.sh。在命令行当中输入:

MacBook-Pro:~$ brew install redis

==> Downloading https://homebrew.bintray.com/bottles/redis-3.2.8.sierra.bottle.2
######################################################################## 100.0%

==> Pouring redis-3.2.8.sierra.bottle.2.tar.gz

==> Caveats

To have launchd start redis now and restart at login:

  brew services start redis

Or, if you don't want/need a background service you can just run:

  redis-server /usr/local/etc/redis.conf

==> Summary

��  /usr/local/Cellar/redis/3.2.8: 11 files, 1.7MB
下载安装完之后,可以使用命令启动redis,命令跟启动效果如下:

MacBook-Pro:~$ redis-server 

9669:C 12 May 11:00:28.543 # Warning: no config file specified, using the default config. In order to specify a config file use redis-server /path/to/redis.conf

9669:M 12 May 11:00:28.545 * Increased maximum number of open files to 10032 (it was originally set to 256).

                _._                                                  

           _.-``__ ''-._                                             

      _.-``    `.  `_.  ''-._           Redis 3.2.8 (00000000/0) 64 bit

  .-`` .-```.  ```\/    _.,_ ''-._                                   

 (    '      ,       .-`  | `,    )     Running in standalone mode

 |`-._`-...-` __...-.``-._|'` _.-'|     Port: 6379

 |    `-._   `._    /     _.-'    |     PID: 9669

  `-._    `-._  `-./  _.-'    _.-'                                   

 |`-._`-._    `-.__.-'    _.-'_.-'|                                  

 |    `-._`-._        _.-'_.-'    |           http://redis.io        

  `-._    `-._`-.__.-'_.-'    _.-'                                   

 |`-._`-._    `-.__.-'    _.-'_.-'|                                  

 |    `-._`-._        _.-'_.-'    |                                  

  `-._    `-._`-.__.-'_.-'    _.-'                                   

      `-._    `-.__.-'    _.-'                                       

          `-._        _.-'                                           

              `-.__.-'                                               

9669:M 12 May 11:00:28.547 # Server started, Redis version 3.2.8

9669:M 12 May 11:00:28.547 * The server is now ready to accept connections on port 6379

好启动了,说点正经的,首先Redis支持的数据存储结构有下列这些(这份表来自于 redis in action ):

数据结构结构存储的值结构的读写能力
STRING可以是字符串、整数或者浮点数对整个字符串或者字符串的其中一部分执行操作;

对整数和浮点数执行自增或者自减
LIST              一个链表,链表上的每个节点都包含了一个字符串从链表的两端push或者pop出元素;

根据偏移量对链表进行修剪;

读取单个或者多个元素;

根据值查找或者移除元素;
SET            包含字符串的无序收集器,并且被包含的每个字符串都是唯一的添加、获取、移除单个元素;

检查一个元素是否存在于集合当中;

计算交集、并集、差集;

从集合里面随机获得元素;
HASH 包含键值对的无序散列表添加、获取、移除单个键值对;

获取所有键值对;
ZSET 字符串成员与浮点分值之间的有序映射,元素的排列顺序由分值的大小决定添加、获取、删除单个元素;

根据分值范围或者成员来获取元素
首先我们使用redis-cli对redis进行直接操作,使用redis-cli非常简单直接输入redis-cli命令即可:

MacBook-Pro:~$ redis-cli 

Redis中的字符串【STRING】

在REDIS中所有数据都以键值对的形式进行存储,所以说每一个数据结构类型的数据都有一个独一无二的KEY,下面就以STRING为例进行尝试使用。

使用的命令如下:

GET  获取存储在指定KEY中的值。

SET  设置一个值到指定的KEY当中。

DEL  删除一个指定KEY中的值(可以应用到任意类型)。

127.0.0.1:6379> SET MY_KEY MY_VALUE    

OK

127.0.0.1:6379> GET MY_KEY

"MY_VALUE"

127.0.0.1:6379> SET MY_KEY MY_NEW_VALUE

OK

127.0.0.1:6379> GET MY_KEY

"MY_NEW_VALUE"

127.0.0.1:6379> DEL MY_KEY

(integer) 1

127.0.0.1:6379> GET MY_KEY

(nil)

Redis 中的列表【LIST】

RPUSH     向列表右边放入一个值

LPUSH      向列表左边放入一个值

LPOP        在列表左边弹出一个值

RPOP        在列表右边弹出一个值

LINDEX     获得列表中指定下标的值

LRANGE   获得列表中一定范围的值

127.0.0.1:6379> RPUSH MY_LIST_KEY VALUE_1 VALUE_2 VALUE_3

(integer) 3

127.0.0.1:6379> LRANGE MY_LIST_KEY 0 -1  注意开启值为0 结束值为-1 可以范围列表中所有数据

1) "VALUE_1"

2) "VALUE_2"

3) "VALUE_3"

127.0.0.1:6379> LPUSH MY_LIST_KEY VALUE_-1

(integer) 4

127.0.0.1:6379> LRANGE MY_LIST_KEY 0 4

1) "VALUE_-1"

2) "VALUE_1"

3) "VALUE_2"

4) "VALUE_3"

127.0.0.1:6379> LPOP MY_LIST_KEY

"VALUE_-1"

127.0.0.1:6379> RPOP MY_LIST_KEY

"VALUE_3"

127.0.0.1:6379> LRANGE MY_LIST_KEY 0 -1

1) "VALUE_1"

2) "VALUE_2"

Redis的集合【SET】
SET和LIS 都可以存储一堆数据,但是和JAVA 一样SET中的数据是唯一,而且SET是无序的集合,所以不能使用PUSH 和 POP 这样的操作。不过我们可以使用SADD命令将数据放入SET当中,使用SREM命令将数据从SET中移除。另外可使用SISMEMBER判断一个元素是否存在在指定的SET当中,由于不能使用LRANGE这样的操作获得元素,SET提供了SMEMBERS命令获得指定SET的所有元素,当然不要乱来,如果一个SET存储过多的数据一次过读取会导致查询缓慢的问题。

SADD   为指定的SET添加元素

SMEMBERS  返回指定SET的所有元素

SISMEMBER 检查给定元素是否存在于集合当中。

SREM    如果给定的元素存在于集合中,那么移除这些元素。

127.0.0.1:6379> SADD MY_SET A1 A2 A3 A4 A5

(integer) 5

127.0.0.1:6379> SMEMBERS MY_SET

1) "A3"

2) "A4"

3) "A2"

4) "A1"

5) "A5"

127.0.0.1:6379> SISMEMBER MY_SET A3

(integer) 1

127.0.0.1:6379> SISMEMBER MY_SET A8

(integer) 0

127.0.0.1:6379> SREM MY_SET A1

(integer) 1

127.0.0.1:6379> SMEMBERS MY_SET

1) "A4"

2) "A3"

3) "A2"

4) "A5"

127.0.0.1:6379> SREM MY_SET A8

(integer) 0

Redis散列【HASH】

这个类似于JAVA中的MAP,散列存储的值可以是字符串或者数字,并且用户可以对散列存储的数据指执行自增或者自减操作,散列就像是一个微缩版本的redis,不少字符串命令都有相应的散列版本。

HSET 在散列里面添加键值对。

HGET 获得指定HASH中的,指定的KEY的数据。

HGETALL  获得HASH中所有键值对

HDEL 删除指定HASH的某一键值对

127.0.0.1:6379> HSET MY_MAP SUB_KEY_1 SUB_VALUE_ABC

(integer) 1

127.0.0.1:6379> HSET MY_MAP SUB_KEY_2 SUB_VALUE_DDD

(integer) 1

127.0.0.1:6379> HGET MY_MAP SUB_KEY_2

"SUB_VALUE_DDD"

127.0.0.1:6379> HGETALL MY_MAP

1) "SUB_KEY_1"

2) "SUB_VALUE_ABC"

3) "SUB_KEY_2"

4) "SUB_VALUE_DDD"

127.0.0.1:6379> HDEL MY_MAP SUB_KEY_1

(integer) 1

127.0.0.1:6379> HGETALL MY_MAP

1) "SUB_KEY_2"

2) "SUB_VALUE_DDD"

127.0.0.1:6379> 

Redis的有序集合【ZSET】
有序集合和和散列我一样,都是存储键值对的,但是不同的是有序集合中的KEY被称为member,每个member都是唯一的。而有序集合中的VALUE被称为分值,分值必须是浮点类型。有序集合集合是REDIS里面唯一既可以根据member访问元素,又可以根据分值和分值的排序来访问的数据结构。

ZADD  将带有分值的member(成员)添加到指定的有序集合中。

ZRANGE  根据元素在有序排序中所处的位置,从有序集合中获得一组数据。

ZRANGEBYSCORE  获得一组给定分值范围内的元素。

ZREM   从有序集合当中移除某个成员

以上就是redis提供的5种数据结构类型,当然命令远不止这些后面的文章会一步步进行详细介绍,不过我还是贴出一些Redis命令参考的网址:http://doc.redisfans.com,当然如果英文6的也可以去官网看:https://redis.io/commands

以下是我根据redis in action 一书中写的一些基于jedis(java 的redis客户端)写的一些实例:

public class App {

private static Jedis jedis;

private static String articleRecommondationList_Key = "articleListByScore";
private static String newArticleList_Key = "articleListByTime";

public static void main(String[] args) {
jedis = new Jedis("127.0.0.1", 6379);

//        Article article = new Article();
//        article.setTime(System.currentTimeMillis() / 1000);
//        article.setTitle("ARTICLE TITLE E");
//        article.setVotes(0);
//        article.setPoster(1);
//
//        addArticle(article);

List<Article> list = getArticleByTime();
System.out.println(list.toString());

articleVote(8,list.get(2));

list = getArticleByScore();
System.out.println(list.toString());

}

//检查是否用户已经投过票
public static boolean checkVote(String articleKey,int userid) {
String voteRcodeKey = "voteRecode:"+articleKey;
if(jedis.sismember(voteRcodeKey,String.valueOf(userid))){
return false;
}
jedis.sadd(voteRcodeKey,String.valueOf(userid));
return true;
}

//创建文章
public static void addArticle(Article article) {
long new_id = jedis.incrBy("article_id_generator", 1);
String articleKey = "article:" + new_id;
article.setKey(articleKey);
jedis.hset(articleKey, "title", article.getTitle());
jedis.hset(articleKey, "poster", String.valueOf(article.getPoster()));
jedis.hset(articleKey, "votes", String.valueOf(article.getVotes()));
jedis.hset(articleKey, "time", String.valueOf(article.getTime()));
newArticleList(articleKey,article.getTime());
articleRecommondationList(articleKey,0);
}

//添加最新文章时间排序
public static void newArticleList(String articleKey, long time) {
jedis.zadd(newArticleList_Key, time, articleKey);
}

//添加文章投票分值
public static void articleRecommondationList(String articleKey, long score) {
jedis.zadd(articleRecommondationList_Key, score, articleKey);
}

//文章投票功能
public static void articleVote(int user, Article article) {
long oneWeekSecond = 60 * 60 * 24 * 7;
long vote_score = 60 * 60 * 24 / 200;

boolean check_result =  checkVote(article.getKey(),user);
if (System.currentTimeMillis() / 1000 - oneWeekSecond > article.getTime() || !check_result) {
System.err.println("System.currentTimeMillis() / 1000  > " + (System.currentTimeMillis() / 1000 - oneWeekSecond > article.getTime()) );
System.err.println("check_result : " + check_result);
System.err.println("false");
return;
}

jedis.zincrby(articleRecommondationList_Key, vote_score, article.getKey());
jedis.hincrBy(article.getKey(), "votes", 1);
}

//获得最新文章列表
public static List<Article> getArticleByTime() {
Set<String> keySet = jedis.zrevrange(newArticleList_Key, 0, -1);
List<Article> articles = new ArrayList<Article>();
for (String item : keySet) {
articles.add(getArticleByKey(item));
}
return articles;
}

//获得最热门的文章列表
public static List<Article> getArticleByScore() {
Set<String> keySet = jedis.zrevrange(articleRecommondationList_Key, 0, -1);
List<Article> articles = new ArrayList<Article>();
for (String item : keySet) {
articles.add(getArticleByKey(item));
}
return articles;
}

//通过文章KEY获得文章对象
public static Article getArticleByKey(String key) {
Article article = new Article();
Map<String, String> map = jedis.hgetAll(key);
Set<Map.Entry<String, String>> set = map.entrySet();
for (Map.Entry<String, String> item : set) {
if (item.getKey().equals("title")) {
article.setTitle(item.getValue());
} else if (item.getKey().equals("poster")) {
article.setPoster(Integer.valueOf(item.getValue()));
} else if (item.getKey().equals("votes")) {
article.setVotes(Integer.valueOf(item.getValue()));
} else if (item.getKey().equals("time")) {
article.setTime(Long.valueOf(item.getValue()));
}
}
article.setKey(key);
return article;
}

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  Jedis Redis