Ajouter les dépendances suivantes
<dependency><groupId>redis.clients</groupId><artifactId>jedis</artifactId><version>2.9.0</version></dependency>
public class Test {public static void main(String[] args) {JedisPoolConfig jedisPoolConfig = new JedisPoolConfig();jedisPoolConfig.setMaxTotal(20);jedisPoolConfig.setMaxIdle(10);jedisPoolConfig.setMinIdle(5);// timeout,这里既是连接超时又是读写超时,从Jedis 2.8开始有区分connectionTimeout和soTimeout的构造函数JedisPool jedisPool = new JedisPool(jedisPoolConfig, "192.168.157.6", 6379, 3000, null);Jedis jedis = null;try {// 从redis连接池里拿出一个连接执行命令jedis = jedisPool.getResource();System.out.println(jedis.set("single", "zhuge"));System.out.println(jedis.get("single"));// 管道示例// 管道的命令执行方式:cat redis.txt | redis‐cli ‐h 127.0.0.1 ‐a password ‐ p 6379 ‐‐pipePipeline pl = jedis.pipelined();for (int i = 0; i < 10; i++) {pl.incr("pipelineKey");pl.set("zhuge" + i, "zhuge");}List<Object> results = pl.syncAndReturnAll();System.out.println(results);// lua脚本模拟一个商品减库存的原子操作// lua脚本命令执行方式:redis‐cli ‐‐eval /tmp/test.lua , 10jedis.set("product_count_10016", "15"); // 初始化商品10016的库存String script = " local count = redis.call('get', KEYS[1]) " +" local a = tonumber(count) "+" local b = tonumber(ARGV[1]) " +" if a >= b then " +" redis.call('set', KEYS[1], count‐b) "+" return 1 " +" end " +" return 0 ";System.out.println("script:"+script);Object obj = jedis.eval(script, Arrays.asList("product_count_10016"), Arrays.asList("10"));System.out.println(obj);} catch (Exception e) {e.printStackTrace();} finally {// 注意这里不是关闭连接,在JedisPool模式下,Jedis会被归还给资源池。if (jedis != null)jedis.close();}}}
Le client peut envoyer plusieurs requêtes à la fois sans attendre la réponse du serveur. Une fois toutes les commandes envoyées, il peut lire la réponse du service en même temps, ce qui peut réduire considérablement le nombre de requêtes. La surcharge de transmission réseau liée à l'exécution de plusieurs commandes. La surcharge réseau liée à l'exécution de plusieurs commandes via un pipeline n'est en réalité équivalente qu'à la surcharge réseau liée à l'exécution d'une seule commande. Il convient de noter que les commandes sont empaquetées et envoyées en mode pipeline, et redis doit mettre en cache les résultats du traitement de toutes les commandes avant de les traiter. Plus vous regroupez de commandes, plus le cache consomme de la mémoire. Ce n’est donc pas que plus vous emballez de commandes, mieux c’est. Chaque commande envoyée dans le pipeline sera exécutée immédiatement par le serveur. Si l'exécution échoue, les informations seront obtenues dans la réponse suivante ; c'est-à-dire que le pipeline n'exprimera pas la sémantique de « toutes les commandes réussissent ensemble ». dans le pipeline échoue et la commande suivante échoue. La commande n'aura aucun effet et continuera à être exécutée.
L'exemple est comme ci-dessus.
Redis a lancé la fonction de script dans la version 2.6, permettant aux développeurs d'utiliser le langage Lua pour écrire des scripts et les transmettre à Redis pour exécution. Les avantages de l'utilisation de scripts sont les suivants :
Les 5 opérations de requête réseau d'origine peuvent être effectuées avec une seule requête. est placé dans redis Terminé sur le serveur. L’utilisation de scripts réduit la latence aller-retour du réseau. C'est similaire aux tuyaux.
Redis exécutera l'intégralité du script dans son ensemble, et aucune autre commande ne sera insérée au milieu. Les tuyaux ne sont pas atomiques, mais les commandes d'opérations par lots Redis (similaires à mset) sont atomiques.
La fonction de transaction fournie avec redis est très inutile et le rapport d'erreurs ne prend pas en charge la restauration, alors que le script Lua de redis est presque a des fonctions de transaction régulières, prend en charge les opérations de rapport d'erreurs et de restauration. Il est officiellement recommandé que si vous souhaitez utiliser la fonction de transaction de redis, vous puissiez utiliser redis lua à la place.
Il y a ce passage dans la documentation officielle du site :
Un script Redis est transactionnel par définition, donc tout ce que vous pouvez faire avec une transaction Redis, vous pouvez également le faire avec un script, et généralement le script sera à la fois plus simple et plus rapide.
À partir de la version Redis2.6.0, via l'interpréteur Lua intégré, vous pouvez utiliser la commande EVAL pour évaluer les scripts Lua . Le format de la commande EVAL
est le suivant :
EVAL script numkeys key [key ...] arg [arg ...]
Le paramètre script est un programme de script Lua, qui sera exécuté dans le contexte du serveur Redis. Ce script ne le fait pas (et ne devrait pas. ) être défini comme une
fonctions Lua. Le paramètre numkeys est utilisé pour spécifier le nombre de paramètres clés. Le paramètre clé key [key …] commence à partir du troisième paramètre de EVAL et représente les clés Redis (clés) utilisées dans le script. Ces paramètres clés peuvent être transmis en Lua via le tableau de variables globales KEYS, utilisez 1
. comme adresse de base à laquelle accéder (KEYS[1], KEYS[2], etc.). À la fin de la commande, les paramètres supplémentaires arg [arg...] qui ne sont pas des paramètres clés sont accessibles dans Lua via le tableau de variables globales ARGV. Le formulaire d'accès est similaire à la variable KEYS (ARGV[1], ARGV. [2], et ainsi de suite). Par exemple
127.0.0.1:6379> eval "return {KEYS[1],KEYS[2],ARGV[1],ARGV[2]}" 2 key1 key2 first second2 1) "key1"3 2) "key2"4 3) "first"5 4) "second"où "return {KEYS[1],KEYS[2],ARGV[1],ARGV[2]}" est le script Lua en cours d'évaluation, et le chiffre 2 spécifie la clé paramètre Le nombre de
, key1 et key2 sont des paramètres clés, accessibles respectivement à l'aide de KEYS[1] et KEYS[2], et les derniers premier et deuxième sont des paramètres
supplémentaires, accessibles via ARGV[ 1] et ARGV[2] pour y accéder. Dans les scripts Lua, vous pouvez utiliser la fonction redis.call() pour exécuter des commandes Redis
, faites attention à ne pas avoir de boucles infinies .Calcul fastidieux. redis est un script d'exécution à processus unique et à thread unique. Les tuyaux ne bloquent pas Redis.
public class Test2 {public static void main(String[] args) {JedisPoolConfig jedisPoolConfig = new JedisPoolConfig();jedisPoolConfig.setMaxTotal(20);jedisPoolConfig.setMaxIdle(10);jedisPoolConfig.setMinIdle(5);String masterName = "mymaster";Set<String> sentinels = new HashSet<String>();sentinels.add(new HostAndPort("192.168.157.6",26379).toString());sentinels.add(new HostAndPort("192.168.157.6",26380).toString());sentinels.add(new HostAndPort("192.168.157.6",26381).toString());// timeout,这里既是连接超时又是读写超时,从Jedis 2.8开始有区分connectionTimeout和soTimeout的构造函数JedisSentinelPool jedisSentinelPool = new JedisSentinelPool(masterName, sentinels, jedisPoolConfig, 3000, null);Jedis jedis = null;try {// 从redis连接池里拿出一个连接执行命令jedis = jedisSentinelPool.getResource();while(true) {Thread.sleep(1000);try {System.out.println(jedis.set("single", "zhuge"));System.out.println(jedis.get("single"));} catch (Exception e) {// TODO Auto-generated catch blocke.printStackTrace();}}} catch (Exception e) {e.printStackTrace();} finally {// 注意这里不是关闭连接,在JedisPool模式下,Jedis会被归还给资源池。if (jedis != null)jedis.close();}}}
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring‐boot‐starter‐data‐redis</artifactId></dependency><dependency><groupId>org.apache.commons</groupId><artifactId>commons‐pool2</artifactId></dependency>#. 🎜🎜#2, configuration principale du projet Springboot
server:port: 8080spring:redis:database: 0timeout: 3000sentinel: #哨兵模式master: mymaster #主服务器所在集群名称nodes: 192.168.0.60:26379,192.168.0.60:26380,192.168.0.60:26381lettuce:pool:max‐idle: 50min‐idle: 10max‐active: 100max‐wait: 1000
@RestControllerpublic class IndexController {private static final Logger logger = LoggerFactory.getLogger(IndexController.class);@Autowiredprivate StringRedisTemplate stringRedisTemplate;/*** 测试节点挂了哨兵重新选举新的master节点,客户端是否能动态感知到* 新的master选举出来后,哨兵会把消息发布出去,客户端实际上是实现了一个消息监听机制,* 当哨兵把新master的消息发布出去,客户端会立马感知到新master的信息,从而动态切换访问的masterip* @throws InterruptedException*/@RequestMapping("/test_sentinel")public void testSentinel() throws InterruptedException {int i = 1;while (true){try {stringRedisTemplate.opsForValue().set("zhuge"+i, i+"");System.out.println("设置key:"+ "zhuge" + i);i++;Thread.sleep(1000);}catch (Exception e){logger.error("错误:", e);}}}}
private ValueOperations<K, V> valueOps;private HashOperations<K, V> hashOps;private ListOperations<K, V> listOps;private SetOperations<K, V> setOps;private ZSetOperations<K, V> zSetOps;
redisTemplate.opsForValue();//操作字符串redisTemplate.opsForHash();//操作hashredisTemplate.opsForList();//操作listredisTemplate.opsForSet();//操作setredisTemplate.opsForZSet();//操作有序set
StringRedisTemplate Hérité de RedisTemplate, il a également les opérations ci-dessus.
StringRedisTemplate utilise la stratégie de sérialisation String par défaut, et les clés et valeurs enregistrées sont sérialisées et enregistrées en utilisant cette stratégie. RedisTemplate utilise par défaut la stratégie de sérialisation du JDK, et les clés et valeurs enregistrées sont sérialisées et enregistrées à l'aide de cette stratégie.
C'est-à-dire que si le contenu est enregistré avec RedisTemplate, vous verrez beaucoup de caractères codés lorsque vous l'ouvrirez dans la console, ce qui est difficile à comprendre.
Redis客户端命令对应的RedisTemplate中的方法列表:
public class Test3 {public static void main(String[] args) throws IOException {JedisPoolConfig jedisPoolConfig = new JedisPoolConfig();jedisPoolConfig.setMaxTotal(20);jedisPoolConfig.setMaxIdle(10);jedisPoolConfig.setMinIdle(5);Set<HostAndPort> jedisClusterNode = new HashSet<HostAndPort>();jedisClusterNode.add(new HostAndPort("192.168.0.61", 8001));jedisClusterNode.add(new HostAndPort("192.168.0.62", 8002));jedisClusterNode.add(new HostAndPort("192.168.0.63", 8003));jedisClusterNode.add(new HostAndPort("192.168.0.61", 8004));jedisClusterNode.add(new HostAndPort("192.168.0.62", 8005));jedisClusterNode.add(new HostAndPort("192.168.0.63", 8006));// timeout,这里既是连接超时又是读写超时,从Jedis 2.8开始有区分connectionTimeout和soTimeout的构造函数JedisCluster jedisCluster = new JedisCluster(jedisClusterNode, 6000, 5000, 10, "zhuge", jedisPoolConfig);try {while(true) {Thread.sleep(1000);try {System.out.println(jedisCluster.set("single", "zhuge"));System.out.println(jedisCluster.get("single"));} catch (Exception e) {// TODO Auto-generated catch blocke.printStackTrace();}}} catch (Exception e) {e.printStackTrace();} finally {// 注意这里不是关闭连接,在JedisPool模式下,Jedis会被归还给资源池。if (jedisCluster != null)jedisCluster.close();}}}
其实集群模式跟哨兵模式很类似,只不过配置文件修改一下即可
server:port: 8080spring:redis:database: 0timeout: 3000password: zhugecluster:nodes:192.168.0.61:8001,192.168.0.62:8002,192.168.0.63:8003lettuce:pool:# 连接池中的最大空闲连接max‐idle: 50# 连接池中最小空闲连接min‐idle: 10max‐active: 100# 连接池阻塞等待时间(负值表示没有限制)max‐wait: 1000
只不过 sentinel换成了 cluster,然后API什么的都是一样的。
Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!