2011-08-01 13 views
65

Aparentemente, Java7 tiene algunos errores desagradables con respecto a la optimización de bucle: Google search.¿Qué tan serio es el error Java7 "Solr/Lucene"?

Según los informes y las descripciones de errores, me resulta difícil juzgar qué tan significativo es este error (a menos que use Solr o Lucene).

Lo que me gustaría saber:

  • ¿Qué probabilidades hay de que mi (cualquiera) del programa se ve afectado?
  • ¿El error es lo suficientemente determinístico como para que las pruebas normales lo capten?

Nota: No puedo hacer que los usuarios de mi programa utilicen -XX:-UseLoopPredicate para evitar el problema.

Respuesta

78

El problema con cualquier error de zona activa es que necesita alcanzar el umbral de compilación (por ejemplo, 10000) antes de poder obtenerlo: por lo tanto, si las pruebas de su unidad son "triviales", probablemente no lo detecte.

Por ejemplo, detectamos el problema de resultados incorrectos en lucene, porque esta prueba en particular crea 20,000 índices de documentos.

En nuestras pruebas asignamos al azar diferentes interfaces (por ejemplo, diferentes implementaciones de Directorio) y parámetros de indexación y tal, y la prueba solo falla el 1% del tiempo, por supuesto es reproducible con la misma semilla aleatoria. También ejecutamos checkindex en cada índice que crean las pruebas, que hacen algunas pruebas de cordura para garantizar que el índice no esté dañado.

Para la prueba que encontramos, si tiene una configuración particular: p. RAMDirectory + PulsingCodec + cargas almacenadas para el campo, luego, una vez que alcanza el umbral de compilación, el bucle de enumeración sobre las contabilizaciones devuelve cálculos incorrectos, en este caso, el número de documentos devueltos para un término! = El docFreq almacenado para el término.

Tenemos un buen número de pruebas de estrés, y es importante tener en cuenta que las aserciones normales en esta prueba en realidad pasan, es la parte de control al final que falla.

El gran problema con esto, es la indexación incremental de los que Lucene trabaja fundamentalmente mediante la fusión de varios segmentos en uno: debido a esto, si estas enumeraciones calcular los datos no válidos, estos datos no válido es entonces almacenado en el índice resultante de la fusión: también conocido como corrupción.

Diría que este error es mucho más engañoso que los errores de punto de acceso anteriores del bucle que hemos detectado (por ejemplo, cosas de bloqueo de registros, https://issues.apache.org/jira/browse/LUCENE-2975). En ese caso obtuvimos deltas de documentos negativos extravagantes, que hacen que sea fácil de atrapar. También solo tuvimos que desenrollar manualmente un solo método para esquivarlo. Por otro lado, la única "prueba" que tuvimos inicialmente para eso fue un gran índice de 10 GB de http://www.pangaea.de/, por lo que fue doloroso reducirlo a este error.

En este caso, pasé una buena cantidad de tiempo (por ejemplo, todas las noches de la semana pasada) tratando de desenrollar manualmente varias cosas, tratando de crear alguna solución para poder esquivar el error y no tener la posibilidad de índices corruptos siendo creado. Podría esquivar algunos casos, pero había muchos más casos que no podría ... y estoy seguro de que si podemos activar esto en nuestras pruebas, hay más casos por ahí ...

+3

Directamente de la fuente. +1 – aroth

+3

Gracias, por cierto, ya que vi varios comentarios al respecto: tenga en cuenta que la configuración de la prueba que captó los "resultados incorrectos" se cometió el 30 de junio (https://issues.apache.org/jira/browse/LUCENE- 3264), Sin embargo, la fecha y hora en el lanzamiento de Java 7 es en realidad el 27 de junio (http://blog.thetaphi.de/2011/07/real-story-behind-java-7-ga-bugs.html), oh, y el error ha estado abierto en Oracle desde el 13 de mayo de todos modos (http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=7044738). –

+2

Gracias Robert por la respuesta detallada de primera mano. Esto es un desastre: mi proyecto actual utiliza una gran cantidad de criptografía y hash criptográficos. Millones de iteraciones en matrices. Bloqueos que podría manejar, pero tener archivos o hashes incorrectamente encriptados puede volverse evidente años atrás con terribles consecuencias. – Carsten

8

Forma simple de reproducir el bicho. Abrir eclipse (Indigo en mi caso), y vaya a Ayuda/Búsqueda. Ingrese una cadena de búsqueda, notará que el eclipse se bloquea. Eche un vistazo al registro.

# Problematic frame: 
# J org.apache.lucene.analysis.PorterStemmer.stem([CII)Z 
# 
# Failed to write core dump. Minidumps are not enabled by default on client versions of Windows 
# 
# If you would like to submit a bug report, please visit: 
# http://bugreport.sun.com/bugreport/crash.jsp 
# 

--------------- T H R E A D --------------- 

Current thread (0x0000000007b79000): JavaThread "Worker-46" [_thread_in_Java, id=264, stack(0x000000000f380000,0x000000000f480000)] 

siginfo: ExceptionCode=0xc0000005, reading address 0x00000002f62bd80e 

Registers: 
+0

¿Es este el mismo Robert descrito? – OscarRyz

+3

no, Narayan describe http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=7070134. Es uno de los errores en java7 que afecta a lucene (porque si usas el proyectista stemer, tu JRE se bloqueará), pero probablemente sea el menos grave, ya que solo obtienes un colapso: no hay posibilidad de corrupción del índice. –

-7

Según tengo entendido, este error solo se encuentra en el servidor jvm. Si ejecuta su programa en el cliente jvm, estará limpio. Si ejecuta su programa en el servidor jvm, depende del programa qué tan grave puede ser el problema.

+6

Esto es engañoso: en mi máquina -cliente es un no-operativo con java 7, y todos los errores todavía ocurren. –

4

El problema, todavía existen a Dic 2, 2012 tanto en Oracle JDK java -version versión java "1.7.0_09" Java (TM) SE Runtime Environment (build 1.7.0_09-b05) Java HotSpot (TM) 64-Bit Server VM (compilación 23.5-b02, modo mixto) y openjdk versión java "1.7.0_09-icedtea" OpenJDK Runtime Environment (fedora-2.3.3.fc17.1-x86_64) OpenJDK 64-Bit Server VM (compilación 23.2-b09, modo mixto)

Extraño que individualmente cualquiera de -XX: -UseLoopPredicate o -XX: LoopU nrollLimit = 1 opción evitar que ocurra un error, pero cuando se usan juntos - JDK falla ver p. ej. https://bugzilla.redhat.com/show_bug.cgi?id=849279

1

Bueno, es dos años después y creo que este error (o una variación de este) todavía está presente en 1.7.0_25-b15 en OSX.

A través de prueba y error muy doloroso, he determinado que usar Java 1.7 con Solr 3.6.2 y autocommit <maxTime>30000</maxTime> parece causar daños en el índice. Parece que solo ocurre con 1.7 y maxTime en 30000- si cambio a Java 1.6, no tengo problemas. Si bajé maxTime a 3000, no tengo problemas.

La JVM no falla, pero hace que RSolr muera con la siguiente traza de pila en Ruby: https://gist.github.com/armhold/6354416. Lo hace de manera confiable después de guardar unos cientos de registros.

Dadas las muchas capas involucradas aquí (Ruby, Sunspot, Rsolr, etc.) no estoy seguro de que pueda reducir esto a algo que definitivamente pruebe un error de JVM, pero parece que eso es lo que está sucediendo aquí. FWIW También he probado JDK 1.7.0_04, y también muestra el problema.