A股上市公司传智教育(股票代码 003032)旗下技术交流社区北京昌平校区

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© 达摩侠 中级黑马   /  2018-12-12 16:49  /  3073 人查看  /  9 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

本帖最后由 达摩侠 于 2018-12-12 16:52 编辑

这篇文章介绍java中嵌入式redis的使用,只需要在java代码中嵌入次插件即可通过运行java代码启动redis服务。
1.maven依赖
[HTML] 纯文本查看 复制代码
<dependency>
  <groupId>it.ozimov</groupId>
  <artifactId>embedded-redis</artifactId>
  <version>0.7.2</version>
</dependency>


简单运行RedisServer:
[Java] 纯文本查看 复制代码
RedisServer redisServer = new RedisServer(6379);
redisServer.start();
// do some work
redisServer.stop();

为RedisServer提供自己的可执行文件:
[Java] 纯文本查看 复制代码
// 1) given explicit file (os-independence broken!)
RedisServer redisServer = new RedisServer("/path/to/your/redis", 6379);

// 2) given os-independent matrix
RedisExecProvider customProvider = RedisExecProvider.defaultProvider()
  .override(OS.UNIX, "/path/to/unix/redis")
  .override(OS.WINDOWS, Architecture.x86, "/path/to/windows/redis")
  .override(OS.Windows, Architecture.x86_64, "/path/to/windows/redis")
  .override(OS.MAC_OS_X, Architecture.x86, "/path/to/macosx/redis")
  .override(OS.MAC_OS_X, Architecture.x86_64, "/path/to/macosx/redis")
  
RedisServer redisServer = new RedisServer(customProvider, 6379);

使用Fluent API创建RedisServer:
[JavaFX] 纯文本查看 复制代码
RedisServer redisServer = RedisServer.builder()
  .redisExecProvider(customRedisProvider)
  .port(6379)
  .slaveOf("locahost", 6378)
  .configFile("/path/to/your/redis.conf")
  .build();

从头创建简单的redis.conf文件:
[AppleScript] 纯文本查看 复制代码
RedisServer redisServer = RedisServer.builder()
  .redisExecProvider(customRedisProvider)
  .port(6379)
  .setting("bind 127.0.0.1") // good for local development on Windows to prevent security popups
  .slaveOf("locahost", 6378)
  .setting("daemonize no")
  .setting("appendonly no")
  .setting("maxmemory 128M")
  .build();

设置群集
嵌入式Redis支持创建Redis集群
使用短暂的端口
在临时端口上使用Redis群集进行简单的redis集成测试,其设置类似于生产中的设置,如下所示:
[AppleScript] 纯文本查看 复制代码
public class SomeIntegrationTestThatRequiresRedis {
  private RedisCluster cluster;
  private Set<String> jedisSentinelHosts;

  @Before
  public void setup() throws Exception {
    //creates a cluster with 3 sentinels, quorum size of 2 and 3 replication groups, each with one master and one slave
    cluster = RedisCluster.builder().ephemeral().sentinelCount(3).quorumSize(2)
                    .replicationGroup("master1", 1)
                    .replicationGroup("master2", 1)
                    .replicationGroup("master3", 1)
                    .build();
    cluster.start();

    //retrieve ports on which sentinels have been started, using a simple Jedis utility class
    jedisSentinelHosts = JedisUtil.sentinelHosts(cluster);
  }
  
  @Test
  public void test() throws Exception {
    // testing code that requires redis running
    JedisSentinelPool pool = new JedisSentinelPool("master1", jedisSentinelHosts);
  }
  
  @After
  public void tearDown() throws Exception {
    cluster.stop();
  }
}

使用预定义端口
在预定义的端口上启动Redis群集,甚至可以混合使用两种方法:
[Java] 纯文本查看 复制代码
public class SomeIntegrationTestThatRequiresRedis {
  private RedisCluster cluster;

  @Before
  public void setup() throws Exception {
    final List<Integer> sentinels = Arrays.asList(26739, 26912);
    final List<Integer> group1 = Arrays.asList(6667, 6668);
    final List<Integer> group2 = Arrays.asList(6387, 6379);
    //creates a cluster with 3 sentinels, quorum size of 2 and 3 replication groups, each with one master and one slave
    cluster = RedisCluster.builder().sentinelPorts(sentinels).quorumSize(2)
                    .serverPorts(group1).replicationGroup("master1", 1)
                    .serverPorts(group2).replicationGroup("master2", 1)
                    .ephemeralServers().replicationGroup("master3", 1)
                    .build();
    cluster.start();
  }
//(...)

有可能我们启动会遇到下面的错误:
[AppleScript] 纯文本查看 复制代码
java.lang.RuntimeException: Can't start redis server. Check logs for details.
    at redis.embedded.AbstractRedisInstance.awaitRedisServerReady(AbstractRedisInstance.java:66)
    at redis.embedded.AbstractRedisInstance.start(AbstractRedisInstance.java:37)
    at redis.embedded.RedisServer.start(RedisServer.java:11)
    at com.bignibou.configuration.session.EmbeddedRedisConfiguration$RedisServerBean.afterPropertiesSet(EmbeddedRedisConfiguration.java:26)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1633)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1570)
    ... 15 more
这个是什么原因呢?我们进一步debug输出redis server的log看是什么问题,redis log如下:
[AppleScript] 纯文本查看 复制代码
The windows version of redis allocates a large memory mapped file for sharing the heap with the forked process used in persistence operations. This file will be created in the current working directory or the directory specified by the 'heapdir' directive in the
.conf file. Windows is reporting that there is insufficient disk space available for this file (Windows error 0x70).
You may fix this probilem by either reducing the size of the Redis heap with the --maxheap flag, or by moving the heap file to a local drive with sufficient space.
Please see the documentation included with the binary distributions for more details on the --maxheap and --heapdir flags.
Redis can not continue, Exiting.

这里的原因是我们启动的时候heap不够,redis server默认的maxheap:1024000000,创建.conf文件时硬盘不够,那如何解决这个错误呢?
[Java] 纯文本查看 复制代码
@Test
public void testAuth() throws Exception {
  RedisServer server = RedisServer.builder().port(6381).setting("maxheap 51200000").build();
  server.start();
}

关于redis maxheap的详细描述如下:
[AppleScript] 纯文本查看 复制代码
# The Redis heap must be larger than the value specified by the maxmemory
# flag, as the heap allocator has its own memory requirements and
# fragmentation of the heap is inevitable. If only the maxmemory flag is
# specified, maxheap will be set at 1.5*maxmemory. If the maxheap flag is
# specified along with maxmemory, the maxheap flag will be automatically
# increased if it is smaller than 1.5*maxmemory.
# 
# maxheap <bytes>
maxheap 51200000

注意:修改时需要考虑可用量,常规情况都无需修改这个参数



9 个回复

倒序浏览
写的好!
回复 使用道具 举报
学习了!
回复 使用道具 举报
回复 使用道具 举报
高建华 来自手机 初级黑马 2018-12-13 13:30:12
报纸
回复 使用道具 举报
回复 使用道具 举报
嵌入redis插件即可用,学习了
回复 使用道具 举报
回复 使用道具 举报
可以  学到了
回复 使用道具 举报
优秀
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马